#include <stdio.h>
#include <math.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <asm/types.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <string.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <arpa/inet.h>
// #include <net/if.h>
#include <unistd.h>
#include <time.h>
#include <ctype.h>
#include <errno.h>
#include <sys/stat.h>
#include <dirent.h>
#include <sys/statvfs.h>
#include <mntent.h>
#include <limits.h>
#include "define.h"
#include "map.h"
#include "ApiBaseInfo.h"
#include "cjson/cJSON.h"
#include "iotaimp.h"
#include "security_manage.h"
#include "http.h"

#define TEST_MAX_NUM 10

ST_SECURITY_RULE g_st_security_rule[50]; //告警规则缓存
int g_st_security_rule_num;
time_t logPublishTime = 0;
ST_DISK_INDICATORS g_diskIndi[20] = {0}; // 已报警分区缓存
int g_partition_num = 0;

extern ob_context g_mqtt_ob;
extern char rule_ini[];
extern ST_MODEL_CTL g_st_model_ctl;
extern char* LOGIN_USER;
extern char* LOGIN_PASSWORD;
extern char g_ServerIp[64];
extern int ACTIVATION_PORT;
extern char* SD_ADDR_PORT;
extern int smc_tls;

typedef struct netinterface_status
{
	char net_name[30];
	int status;
} netinterface_status;

typedef struct {
	S_DATA_REPORT_DISK_ALARM disk_data[20];
	int count;							//数据的实际个数
	time_t currTime;					//数据的获取时间
} S_DISK_DATA_COLLECTION;
S_DISK_DATA_COLLECTION  g_disk_data = { 0 };

#define RULEFILE "conf/rule.ini"
#define DECRYPT_KEY "\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11"

#define SYS_DISK_BUFF_LEN 256
#define SYS_DISK_NAME_LEN 80
#define NET_NUMS 3

#define BUFLEN 20480
#define TOPIC_SECURITY "/v1/devices/security/events"

#define ALARM_SERVICE_USAGE "usageOverLimitAlarm"
#define ALARM_SERVICE_NETPORT "deviceSecurity"
#define ALARM_SERVICE_NETLINK "netlinkAlarm"

char g_net_check_str[32]; // 网口检测
int G_NET_CHECK_FLAG;
ST_SYS_INDICATORS g_sys_indicators;

// 根据模块定义全局的网络延时结构体
ST_NET_CONTEXT g_device_netContext;		 // 终端
ST_NET_CONTEXT g_security_netContext;	 // 告警
ST_NET_CONTEXT g_diagnostics_netContext; // 诊断
ST_NETINFO g_all_netInfo;				 // 全模块

// tools start...
#define print_buffer_hex(prefix, buf, size)                              \
	dzlog_debug("------------%s, size: [%d]------------", prefix, size); \
	hdzlog_debug(buf, size)

char *hex_to_string(const char *buf, int size)
{
	int len = size * 2 + 1;
	char *out = malloc(len);
	int i = 0, offset = 0;
	while (i < size)
	{
		unsigned char ch = buf[i];
		sprintf(out + offset, "%02x", ch);
		offset += 2;
		++i;
	}
	out[len - 1] = '\0';

	return out;
}

void process_command(char *input)
{
	if (strncmp(input, "cd", 2) == 0)
	{
		// 检查 "cd" 后面的内容是否只有空格或没有内容
		char *ptr = input + 2; // 指向 "cd" 后面的第一个字符
		while (*ptr != '\0' && isspace((unsigned char)*ptr))
		{
			ptr++; // 跳过所有空格
		}
		if (*ptr == '\0')
		{							   // 后面没有其他字符或只有空格
			strcpy(input, "cd /root"); // 修改输入字符串为 "cd /root"
		}
	}
}

void getSubstringOrOriginal(const char *str, char *buffer, size_t buffer_size)
{
	const char *cd_judgment_indicator1 = strstr(str, "cd: ");
	const char *cd_judgment_indicator2 = strstr(str, "No such file or directory");

	if (cd_judgment_indicator1 == NULL || cd_judgment_indicator2 == NULL)
	{
		strncpy(buffer, str, buffer_size - 1);
		buffer[buffer_size - 1] = '\0'; // 确保缓冲区以 '\0' 结尾
	}
	else
	{ // 均符合 定位： cd 非法目录
		size_t length = strlen(cd_judgment_indicator1);
		if (length >= buffer_size)
		{
			strncpy(buffer, cd_judgment_indicator1, buffer_size - 1);
			buffer[buffer_size - 1] = '\0'; // 确保缓冲区以 '\0' 结尾
		}
		else
		{
			strcpy(buffer, cd_judgment_indicator1);
		}
	}
}

void remove_left_spaces(char *str)
{
	int i, j;
	int len = strlen(str);
	for (i = 0; i < len; i++)
	{
		if (!isspace(str[i]))
		{
			break;
		}
	}
	for (j = i; j < len; j++)
	{
		str[j - i] = str[j];
	}
	str[j - i] = '\0';
}

void replaceChar(char *str, char oldChar, char newChar)
{
	int len = strlen(str); // 获取字符串长度
	int i;
	for (i = 0; i < len; i++)
	{
		if (str[i] == oldChar)
		{
			str[i] = newChar; // 替换指定字符
		}
	}
}

// tools end...

// hash相关 start
#define HASHSIZE 10000

// 定义哈希表结构体
typedef struct
{
	ST_CMD_CONTEXT **data;
	int size;
} HashMap;

// 计算哈希值
unsigned int hash(const char *key)
{
	unsigned int hashval = 0;
	while (*key)
	{
		hashval = (hashval << 5) + *key++;
	}
	return hashval % HASHSIZE; // 这里假设哈希表大小为10000
}

// 向哈希表中插入键值对
void hash_put(HashMap *map, const char *key, ST_CMD_CONTEXT *value)
{
	unsigned int hashval = hash(key);
	map->data[hashval] = value;
}

// 从哈希表中获取键对应的值
ST_CMD_CONTEXT *hash_get(HashMap *map, const char *key)
{
	unsigned int hashval = hash(key);
	return map->data[hashval];
}
// hash相关 end
HashMap g_cmd_map;
HashMap g_net_map;

char *g_rule_text[128] = {"mqtt_alarm_rule_cpuusage", "mqtt_alarm_rule_memusage", "mqtt_alarm_rule_diskusage", "mqtt_alarm_rule_cputemp","mqtt_alarm_rule_netlinkdelay","mqtt_alarm_rule_netlinkbreak","mqtt_alarm_rule_netlinkloss"};

void readAlarmRule(dictionary *ini)
{
	memset(g_st_security_rule, 0x00, sizeof(g_st_security_rule));
	// cpu 使用率
	strcpy(g_st_security_rule[0].ruleId, iniparser_getstring(ini, "mqtt_alarm_rule_cpuusage:ruleid", "NULL"));
	strcpy(g_st_security_rule[0].action, iniparser_getstring(ini, "mqtt_alarm_rule_cpuusage:action", "NULL"));
	strcpy(g_st_security_rule[0].indicator, iniparser_getstring(ini, "mqtt_alarm_rule_cpuusage:indicator", "NULL"));
	strcpy(g_st_security_rule[0].severity, iniparser_getstring(ini, "mqtt_alarm_rule_cpuusage:severity", "NULL"));
	g_st_security_rule[0].threshold = iniparser_getint(ini, "mqtt_alarm_rule_cpuusage:threshold", -1);
	strcpy(g_st_security_rule[0].operator, iniparser_getstring(ini, "mqtt_alarm_rule_cpuusage:operator", "NULL"));
	strcpy(g_st_security_rule[0].unit, iniparser_getstring(ini, "mqtt_alarm_rule_cpuusage:unit", "NULL"));
	g_st_security_rule[0].duration = iniparser_getint(ini, "mqtt_alarm_rule_cpuusage:duration", 0);
	g_st_security_rule[0].count = iniparser_getint(ini, "mqtt_alarm_rule_cpuusage:count", 0);
	pthread_mutex_init(&g_st_security_rule[0].lock, NULL);
	g_st_security_rule[0].ruleType=1;
	// 内存使用率
	strcpy(g_st_security_rule[1].ruleId, iniparser_getstring(ini, "mqtt_alarm_rule_memusage:ruleid", "NULL"));
	strcpy(g_st_security_rule[1].action, iniparser_getstring(ini, "mqtt_alarm_rule_memusage:action", "NULL"));
	strcpy(g_st_security_rule[1].indicator, iniparser_getstring(ini, "mqtt_alarm_rule_memusage:indicator", "NULL"));
	strcpy(g_st_security_rule[1].severity, iniparser_getstring(ini, "mqtt_alarm_rule_memusage:severity", "NULL"));
	g_st_security_rule[1].threshold = iniparser_getint(ini, "mqtt_alarm_rule_memusage:threshold", -1);
	strcpy(g_st_security_rule[1].operator, iniparser_getstring(ini, "mqtt_alarm_rule_memusage:operator", "NULL"));
	strcpy(g_st_security_rule[1].unit, iniparser_getstring(ini, "mqtt_alarm_rule_memusage:unit", "NULL"));
	g_st_security_rule[1].duration = iniparser_getint(ini, "mqtt_alarm_rule_memusage:duration", 0);
	g_st_security_rule[1].count = iniparser_getint(ini, "mqtt_alarm_rule_memusage:count", 0);
	pthread_mutex_init(&g_st_security_rule[1].lock, NULL);
	g_st_security_rule[1].ruleType=1;
	// 磁盘使用率
	strcpy(g_st_security_rule[2].ruleId, iniparser_getstring(ini, "mqtt_alarm_rule_diskusage:ruleid", "NULL"));
	strcpy(g_st_security_rule[2].action, iniparser_getstring(ini, "mqtt_alarm_rule_diskusage:action", "NULL"));
	strcpy(g_st_security_rule[2].indicator, iniparser_getstring(ini, "mqtt_alarm_rule_diskusage:indicator", "NULL"));
	strcpy(g_st_security_rule[2].severity, iniparser_getstring(ini, "mqtt_alarm_rule_diskusage:severity", "NULL"));
	g_st_security_rule[2].threshold = iniparser_getint(ini, "mqtt_alarm_rule_diskusage:threshold", -1);
	strcpy(g_st_security_rule[2].operator, iniparser_getstring(ini, "mqtt_alarm_rule_diskusage:operator", "NULL"));
	strcpy(g_st_security_rule[2].unit, iniparser_getstring(ini, "mqtt_alarm_rule_diskusage:unit", "NULL"));
	g_st_security_rule[2].duration = iniparser_getint(ini, "mqtt_alarm_rule_diskusage:duration", 0);
	g_st_security_rule[2].count = iniparser_getint(ini, "mqtt_alarm_rule_diskusage:count", 0);
	g_st_security_rule[2].ruleType=1;
	// cpu 温度
	strcpy(g_st_security_rule[3].ruleId, iniparser_getstring(ini, "mqtt_alarm_rule_cputemp:ruleid", "NULL"));
	strcpy(g_st_security_rule[3].action, iniparser_getstring(ini, "mqtt_alarm_rule_cputemp:action", "NULL"));
	strcpy(g_st_security_rule[3].indicator, iniparser_getstring(ini, "mqtt_alarm_rule_cputemp:indicator", "NULL"));
	strcpy(g_st_security_rule[3].severity, iniparser_getstring(ini, "mqtt_alarm_rule_cputemp:severity", "NULL"));
	g_st_security_rule[3].threshold = iniparser_getint(ini, "mqtt_alarm_rule_cputemp:threshold", -1);
	strcpy(g_st_security_rule[3].operator, iniparser_getstring(ini, "mqtt_alarm_rule_cputemp:operator", "NULL"));
	strcpy(g_st_security_rule[3].unit, iniparser_getstring(ini, "mqtt_alarm_rule_cputemp:unit", "NULL"));
	g_st_security_rule[3].duration = iniparser_getint(ini, "mqtt_alarm_rule_cputemp:duration", 0);
	g_st_security_rule[3].count = iniparser_getint(ini, "mqtt_alarm_rule_cputemp:count", 0);
	pthread_mutex_init(&g_st_security_rule[3].lock, NULL);
	g_st_security_rule[3].ruleType=1;
	// 网线插入
	strcpy(g_st_security_rule[4].ruleId, "99999995");
	strcpy(g_st_security_rule[4].action, "ADD");
	strcpy(g_st_security_rule[4].indicator, "NetCableInsert");
	strcpy(g_st_security_rule[4].severity, "Warning");
	strcpy(g_st_security_rule[4].operator, "");
	strcpy(g_st_security_rule[4].unit, "");

	// 网线拔出
	strcpy(g_st_security_rule[5].ruleId, "99999996");
	strcpy(g_st_security_rule[5].action, "ADD");
	strcpy(g_st_security_rule[5].indicator, "NetCablePullOut");
	strcpy(g_st_security_rule[5].severity, "Warning");
	strcpy(g_st_security_rule[5].operator, "");
	strcpy(g_st_security_rule[5].unit, "");

	// 链路时延
	strcpy(g_st_security_rule[6].ruleId, iniparser_getstring(ini, "mqtt_alarm_rule_netlinkdelay:ruleid", "99999997"));
	strcpy(g_st_security_rule[6].action, iniparser_getstring(ini, "mqtt_alarm_rule_netlinkdelay:action", "ADD"));
	strcpy(g_st_security_rule[6].indicator, iniparser_getstring(ini, "mqtt_alarm_rule_netlinkdelay:indicator", "netlinkDelay"));
	strcpy(g_st_security_rule[6].severity, iniparser_getstring(ini, "mqtt_alarm_rule_netlinkdelay:severity", "Warning"));
	strcpy(g_st_security_rule[6].operator, iniparser_getstring(ini, "mqtt_alarm_rule_netlinkdelay:operator", "GT"));
	strcpy(g_st_security_rule[6].unit, iniparser_getstring(ini, "mqtt_alarm_rule_netlinkdelay:unit", "ms"));
	g_st_security_rule[6].duration = iniparser_getint(ini, "mqtt_alarm_rule_netlinkdelay:duration", 0);
	g_st_security_rule[6].count = iniparser_getint(ini, "mqtt_alarm_rule_netlinkdelay:count", 0);

	g_st_security_rule[6].threshold = iniparser_getint(ini, "mqtt_alarm_rule_netlinkdelay:threshold", 800);
	pthread_mutex_init(&g_st_security_rule[6].lock, NULL);
	g_st_security_rule[6].ruleType=1;

	// 链路中断
	// strcpy(g_st_security_rule[7].ruleId, iniparser_getstring(ini, "mqtt_alarm_rule_netlinkbreak:ruleid", "99999998"));
	// strcpy(g_st_security_rule[7].action, iniparser_getstring(ini, "mqtt_alarm_rule_netlinkbreak:action", "ADD"));
	// strcpy(g_st_security_rule[7].indicator, iniparser_getstring(ini, "mqtt_alarm_rule_netlinkbreak:indicator", "netlinkBreak"));
	// strcpy(g_st_security_rule[7].severity, iniparser_getstring(ini, "mqtt_alarm_rule_netlinkbreak:severity", "Warning"));
	// strcpy(g_st_security_rule[7].operator, iniparser_getstring(ini, "mqtt_alarm_rule_netlinkbreak:operator", "GT"));
	// strcpy(g_st_security_rule[7].unit, iniparser_getstring(ini, "mqtt_alarm_rule_netlinkbreak:unit", "ms"));
	// g_st_security_rule[7].duration = iniparser_getint(ini, "mqtt_alarm_rule_netlinkbreak:duration", 0);
	// g_st_security_rule[7].count = iniparser_getint(ini, "mqtt_alarm_rule_netlinkbreak:count", 0);
	// g_st_security_rule[7].threshold = iniparser_getint(ini, "mqtt_alarm_rule_netlinkbreak:threshold", 2000);

	// g_st_security_rule[7].isAlarm = 0;
	// pthread_mutex_init(&g_st_security_rule[7].lock, NULL);
	// g_st_security_rule[7].ruleType=1;

	// 链路丢包
	// strcpy(g_st_security_rule[7].ruleId, iniparser_getstring(ini, "mqtt_alarm_rule_netlinkloss:ruleid", "99999999"));
	// strcpy(g_st_security_rule[7].action, iniparser_getstring(ini, "mqtt_alarm_rule_netlinkloss:action", "ADD"));
	// strcpy(g_st_security_rule[7].indicator, iniparser_getstring(ini, "mqtt_alarm_rule_netlinkloss:indicator", "netlinkLossPacket"));
	// strcpy(g_st_security_rule[7].severity, iniparser_getstring(ini, "mqtt_alarm_rule_netlinkloss:severity", "Warning"));
	// g_st_security_rule[7].threshold = iniparser_getint(ini, "mqtt_alarm_rule_netlinkloss:threshold", 50);
	// strcpy(g_st_security_rule[7].operator, iniparser_getstring(ini, "mqtt_alarm_rule_netlinkloss:operator", "GT"));
	// strcpy(g_st_security_rule[7].unit, iniparser_getstring(ini, "mqtt_alarm_rule_netlinkloss:unit", ""));
	// g_st_security_rule[7].duration = iniparser_getint(ini, "mqtt_alarm_rule_netlinkloss:duration", 0);
	// g_st_security_rule[7].count = iniparser_getint(ini, "mqtt_alarm_rule_netlinkloss:count", 0);
	// g_st_security_rule[7].isAlarm = 0;
	// pthread_mutex_init(&g_st_security_rule[7].lock, NULL);
	// g_st_security_rule[7].ruleType=1;

	g_st_security_rule_num = 7;

	//初始化磁盘分区告警start //add by lsc 20250817
	char key[128];
	
	int nsec = iniparser_getnsec(ini);
	for (int i = 0; i < nsec; i++) {
		const char* sec_name = iniparser_getsecname(ini, i);
		// 检测磁盘分区规则 (以 mqtt_alarm_rule_disk_ 开头)
		if (strncmp(sec_name, "mqtt_alarm_rule_disk_", 21) == 0) {
			const char* partition = sec_name + 21; // 提取分区路径
			strncpy(g_st_security_rule[g_st_security_rule_num].ruleValueRemark, partition, sizeof(g_st_security_rule[g_st_security_rule_num].ruleValueRemark));
			snprintf(key, sizeof(key), "%s:ruleid", sec_name);
			strncpy(g_st_security_rule[g_st_security_rule_num].ruleId, iniparser_getstring(ini, key, ""), sizeof(g_st_security_rule[g_st_security_rule_num].ruleId));
			snprintf(key, sizeof(key), "%s:action", sec_name);
			strncpy(g_st_security_rule[g_st_security_rule_num].action, iniparser_getstring(ini, key, ""), sizeof(g_st_security_rule[g_st_security_rule_num].action));
			snprintf(key, sizeof(key), "%s:indicator", sec_name);
			strncpy(g_st_security_rule[g_st_security_rule_num].indicator, iniparser_getstring(ini, key, ""), sizeof(g_st_security_rule[g_st_security_rule_num].indicator));
			snprintf(key, sizeof(key), "%s:severity", sec_name);
			strncpy(g_st_security_rule[g_st_security_rule_num].severity, iniparser_getstring(ini, key, ""), sizeof(g_st_security_rule[g_st_security_rule_num].severity));
			snprintf(key, sizeof(key), "%s:threshold", sec_name);
			g_st_security_rule[g_st_security_rule_num].threshold = iniparser_getint(ini, key, -1);
			snprintf(key, sizeof(key), "%s:operator", sec_name);
			strncpy(g_st_security_rule[g_st_security_rule_num].operator, iniparser_getstring(ini, key, ""), sizeof(g_st_security_rule[g_st_security_rule_num].operator));
			snprintf(key, sizeof(key), "%s:unit", sec_name);
			strncpy(g_st_security_rule[g_st_security_rule_num].unit, iniparser_getstring(ini, key, ""), sizeof(g_st_security_rule[g_st_security_rule_num].unit));
			snprintf(key, sizeof(key), "%s:duration", sec_name);
			g_st_security_rule[g_st_security_rule_num].duration = iniparser_getint(ini, key, 0);
			snprintf(key, sizeof(key), "%s:count", sec_name);
			g_st_security_rule[g_st_security_rule_num].count = iniparser_getint(ini, key, 0);
			g_st_security_rule[g_st_security_rule_num].isAlarm = 0;
			g_st_security_rule[g_st_security_rule_num].ruleType = 1;
			
			g_st_security_rule_num++;
		}
	}
	//初始化磁盘分区告警end
}

// 注意size，不要取太多
static int popenCmdS(char *cmd, char *result, int size)
{
	if (!cmd || strlen(cmd) == 0)
	{
		return -1;
	}
	FILE *read_fp;
	char buf[4096 + 1] = {0};
	memset(buf, 0, sizeof(buf));
	read_fp = popen(cmd, "r");
	if (read_fp == NULL)
	{
		dzlog_error("popenCmdS error[read_fp == NULL],cmd[%s],popenCmdS:%s,size[%d]", cmd, buf, size);
		return -3;
	}
	int len = fread(buf, 1, 4096, read_fp);
	if (len < 0)
	{
		dzlog_error("popenCmdS error[fread len < 0],cmd[%s],popenCmdS:%s,size[%d]", cmd, buf, size);
		pclose(read_fp);
		return -5;
	}

	getSubstringOrOriginal(buf, result, size); // cd 健壮性处理
	// strncpy(result, buf, size);

	int status = pclose(read_fp);
	if (status == -1 && strstr(cmd, "ping") == 0 && strstr(cmd, "top") == 0)
	{
		perror("cmd exec error!");
		// printf("222Error: %s\n", strerror(errno));
		strcpy(result, strerror(errno));
		dzlog_error("popenCmdS pclose error[%s]", result);
		return -6;
	}

	return 0;
}

int getCpuUsage(char *result)
{
	/*
	if(!result)
	{
		return -1;
	}
	char *cmdstr = "top -b -n1 | fgrep \"idle\" | grep -v \"fgrep\" | awk \'{print 100-$8}\' ";
	int ret = popenCmdS(cmdstr,result,32);
	(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
	return ret;	*/
	// char result[255]={0};
	int ret = cpuUsed(result);
	if (ret < 0)
		return -1;
	char *p = strstr(result, "%");
	if (p)
		*p = '\0';

	return 0;
}

int getMemUsage(char *result)
{
	if (!result)
	{
		return -1;
	}
	int ret = popenCmdS("free -m | fgrep \"Mem\" | awk \'{printf \"%d\", ($3)/$2*100}\'", result, 32);
	(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
	return ret;
}

int getDiskUsage1(char *result)
{
	if (!result)
	{
		return -1;
	}
	int ret = popenCmdS("df -m | awk \'{a+=$2}END{print a}\'", result, 32);
	(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
	strcat(result, "MB");
	return ret;
}

// 检查是否为虚拟文件系统
bool is_virtual_filesystem(const char* fs_type) {
	const char* virtual_fs[] = {
		"tmpfs", "proc", "sysfs", "devtmpfs", "devpts", "cgroup",
		"cgroup2", "overlay", "squashfs", "ramfs", "rootfs", "fuse",
		"autofs", "mqueue", "debugfs", "tracefs", "configfs", "binfmt_misc",
		"securityfs", "pstore", "efivarfs", "hugetlbfs", "rpc_pipefs", NULL
	};

	for (int i = 0; virtual_fs[i] != NULL; i++) {
		if (strcmp(fs_type, virtual_fs[i]) == 0) {
			return true;
		}
	}
	return false;
}

double  getTotalDiskUsage() {
	FILE* fp = fopen("/proc/mounts", "r");
	if (!fp) {
		perror("Failed to open /proc/mounts");
		return 0.0;
	}

	unsigned long long total_bytes = 0;
	unsigned long long used_bytes = 0;
	char line[1024];

	while (fgets(line, sizeof(line), fp)) {
		// Split line into tokens
		char* tokens[6] = { 0 };
		int i = 0;
		char* token = strtok(line, " \t\n");
		while (token && i < 6) {
			tokens[i++] = token;
			token = strtok(NULL, " \t\n");
		}
		if (i < 2) continue; // Require at least device and mountpoint

		char device[PATH_MAX];
		char mountpoint[PATH_MAX];
		char fs_type[PATH_MAX];

		strncpy(device, tokens[0], PATH_MAX);
		strncpy(mountpoint, tokens[1], PATH_MAX);
		strncpy(fs_type, tokens[2], PATH_MAX);

		if (is_virtual_filesystem(fs_type)) {
			continue;
		}

		// Resolve device paths for UUID and LABEL
		char resolved_device[PATH_MAX] = "INVALID";
		if (strncmp(device, "/dev/", 5) == 0) {
			strcpy(resolved_device, device);
		}
		else if (strncmp(device, "UUID=", 5) == 0) {
			snprintf(resolved_device, sizeof(resolved_device), "/dev/disk/by-uuid/%s", device + 5);
		}
		else if (strncmp(device, "LABEL=", 6) == 0) {
			snprintf(resolved_device, sizeof(resolved_device), "/dev/disk/by-label/%s", device + 6);
		}
		else {
			continue; // Unsupported device specification
		}

		// Check if resolved device is a valid block device
		struct stat st;
		if (stat(resolved_device, &st) != 0 || !S_ISBLK(st.st_mode)) {
			continue;
		}

		// Get filesystem stats
		struct statvfs buf;
		if (statvfs(mountpoint, &buf) != 0) {
			fprintf(stderr, "statvfs failed on %s: %s", mountpoint, strerror(errno));
			continue;
		}

		unsigned long long total = (unsigned long long)buf.f_blocks * buf.f_frsize;
		unsigned long long free = (unsigned long long)buf.f_bfree * buf.f_frsize;

		total_bytes += total;
		used_bytes += (total - free);
	}

	fclose(fp);
	double usage = 0.0;
	if (total_bytes == 0) {
		printf("No disk partitions found.");
	}
	else {
		usage = (double)used_bytes / total_bytes * 100.0;
		printf("Total disk usage: %.2f%%", usage);
		//dzlog_info("getTotalDiskUsage used_bytes[%llu] total_bytes[%llu],usage[%f]", used_bytes, total_bytes, usage);
	}
	
	return usage;
}


int getDiskUsage(ST_DISK_INDICATORS *diskIndi, int exceedValue, int *diskCount, int i)
{
	FILE *fp;
	// int i = 0;
	char filesystem[SYS_DISK_NAME_LEN], available[SYS_DISK_NAME_LEN], use[SYS_DISK_NAME_LEN], mounted[SYS_DISK_NAME_LEN], buf[SYS_DISK_BUFF_LEN];
	double used, blocks, used_rate;
	fp = popen("df", "r");
	fgets(buf, SYS_DISK_BUFF_LEN, fp);
	double dev_total = 0, dev_used = 0;
	bool istrue = false;
	while (6 == fscanf(fp, "%s %lf %lf %s %s %s", filesystem, &blocks, &used, available, use, mounted))
	{

		if ((used / blocks * 100) >= (float)exceedValue)
		{
			int i = 0;
			for (; i < g_partition_num; i++)
			{
				if (strcmp(g_diskIndi[i].partition, filesystem) == 0)
				{
					istrue = true;
					break;
				}
			}
			if (istrue)
			{
				continue;
			}
			g_diskIndi[*diskCount].diskUsage = (used / blocks * 100);
			strcpy(g_diskIndi[*diskCount].partition, filesystem);
			g_diskIndi[*diskCount].indication = 1;
			g_partition_num++;
			diskIndi[*diskCount].diskUsage = (used / blocks * 100);
			strcpy(diskIndi[*diskCount].partition, filesystem);
			(*diskCount)++;
		}
		else
		{
			// 从已报警分区缓存删除当前分区
			int i = 0;
			for (; i < g_partition_num; i++)
			{
				if (strcmp(g_diskIndi[i].partition, filesystem) == 0)
				{
					break;
				}
			}
			for (; i < g_partition_num - 1; i++)
			{
				g_diskIndi[i] = g_diskIndi[i + 1];
			}

			if (i < g_partition_num)
			{
				g_partition_num--;
			}

			// 0320暂时注释，现在的硬盘使用率报警，所有分区的报警共用一个报警id,所以不好消警，待后续
			////构造硬盘分区使用率消警数据
			// diskIndi[*diskCount].diskUsage = (used / blocks * 100);
			// strcpy(diskIndi[*diskCount].partition, filesystem);
			// g_diskIndi[*diskCount].indication = 0;
		}
	}

	// used_rate = (dev_used/dev_total)*SYS_100_PERSENT;
	pclose(fp);

	return 0;
}

int getCpuTemp(char *result)
{
	if (!result)
	{
		return -1;
	}
	// int ret = popenCmdS("cat /sys/class/thermal/thermal_zone0/temp ", result, 32);
	// (result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');

	int ret = cpuTemp(result);

	return ret;
}

int getNetPortStatus(netinterface_status *NetPort, int portNum)
{
	// dzlog_info("getNetPortStatus start ");
	if (system("swconfig list") == 0)
	{
		char result[32];
		int i;
		int netStatus = 0;
		char cmd[128] = {0};
		for (i = 0; i < 5; i++)
		{
			netStatus = 0;
			sprintf(cmd, "swconfig dev switch0 port %d get link | awk \'{print $2}\' | cut -d\":\" -f2", i);
			popenCmdS(cmd, result, 32);
			(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
			if (strstr(result, "up"))
				netStatus = 1;
			NetPort[i].status = netStatus;

			if (i == 0)
			{
				sprintf(NetPort[i].net_name, "eth1");
			}
			else if (i == 1)
			{
				sprintf(NetPort[i].net_name, "eth0");
			}
			else
			{
				sprintf(NetPort[i].net_name, "port %d", i);
			}

		}
	}
	else
	{
		struct dirent **entries;
		int i = 0;
		int num_entries = scandir("/sys/class/net/", &entries, NULL, alphasort);

		for (i = 0; i < num_entries; i++)
		{
			if (strncmp(entries[i]->d_name, "e", 1) == 0)
			{
				strcpy(NetPort[i].net_name, entries[i]->d_name);
				char file_full[50];
				sprintf(file_full, "/sys/class/net/%s/carrier", entries[i]->d_name);

				FILE *fp = fopen(file_full, "r");
				char status[10];

				if (fgets(status, sizeof(status), fp))
				{
					NetPort[i].status = atoi(status);
				}
				//dzlog_debug("netname = %s,status = %s", NetPort[i].net_name, status);
				fclose(fp);
			}
			free_s(entries[i]);
		}
		free_s(entries);
	}
	return 0;
}

int getNetPortStatus_hmNvr(int *NetPort, int portNum)
{
	char result[32];
	int i;
	int netStatus = 0;
	char cmd[128] = {0};
	for (i = 0; i < portNum; i++)
	{
		netStatus = 0;
		sprintf(cmd, "cat /sys/class/net/eth%d/carrier", i);
		popenCmdS(cmd, result, 32);
		(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
		netStatus = atoi(result);
		NetPort[i] = netStatus;
	}

	return 0;
}

// int getNetPortStatus_ubuntu(int *NetPort, int portNum)
// {
// 	char result[32];
// 	int i;
// 	int netStatus = 0;
// 	char cmd[128] = {0};
// 	for (i = 0; i < portNum; i++)
// 	{
// 		netStatus = 0;
// 		sprintf(cmd, "cat /sys/class/net/enp%ds0/carrier", i);
// 		popenCmdS(cmd, result, 32);
// 		(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
// 		netStatus = atoi(result);
// 		NetPort[i] = netStatus;
// 		dzlog_info("getNetPortStatus_ubuntu >> enp%ds0 [%d]", i, NetPort[i]);
// 	}

// 	return 0;
// }

int security_rule_proc(char *pcJson)
{
	dzlog_info("security_rule_proc start");
	// dzlog_info("security_rule_proc in ......");
	cJSON *json = NULL;
	cJSON *params = NULL;
	cJSON *item = NULL;
	char mid[64] = {0};
	char zone[32] = {0};
	char node[32] = {0};
	char deviceSn[32] = {0};
	char deviceId[32] = {0};
	char msgTime[32] = {0};
	char ruleId[32] = {0};
	char action[32] = {0};
	char indicator[32] = {0};
	char severity[32] = {0};
	char operator[8] = {0};
	char unit[8] = {0};
	char ruleValueRemark[64] = { 0 };
	char tmp[128] = {0};
	int duration = 0;
	int count = 0;
	int threshold = 0;

	dictionary *ini = iniparser_load(rule_ini);
	if (ini == NULL)
	{
		dzlog_error("iniparser_load error file[%s]!", rule_ini);
		return -1;
	}
	json = cJSON_Parse(pcJson);
	strcpy(mid, cJSON_GetObjectItem(json, "mid")->valuestring);
	strcpy(deviceSn, cJSON_GetObjectItem(json, "deviceSn")->valuestring);
	strcpy(msgTime, cJSON_GetObjectItem(json, "msgTime")->valuestring);
	if (cJSON_GetObjectItem(json, "zone"))
	{
		strcpy(zone, cJSON_GetObjectItem(json, "zone")->valuestring);
	}
	if (cJSON_GetObjectItem(json, "node"))
	{
		strcpy(node, cJSON_GetObjectItem(json, "node")->valuestring);
	}
	if (cJSON_GetObjectItem(json, "deviceId"))
	{
		strcpy(deviceId, cJSON_GetObjectItem(json, "deviceId")->valuestring);
	}
	// 解析columns
	params = cJSON_GetObjectItem(json, "params");
	if (!params)
	{
		dzlog_error("cJSON_GetObjectItem error no params!");
		cJSON_Delete(json);
		iniparser_freedict(ini);
		return -1;
	}
	int param_size = cJSON_GetArraySize(params);
	for (int j = 0; j < param_size; j++)
	{
		memset(ruleValueRemark, 0, sizeof(ruleValueRemark));
		item = cJSON_GetArrayItem(params, j);
		strcpy(ruleId, cJSON_GetObjectItem(item, "ruleId")->valuestring);
		strcpy(action, cJSON_GetObjectItem(item, "action")->valuestring);
		strcpy(indicator, cJSON_GetObjectItem(item, "indicator")->valuestring);
		strcpy(severity, cJSON_GetObjectItem(item, "severity")->valuestring);
		threshold = cJSON_GetObjectItem(item, "threshold")->valueint;
		if (cJSON_GetObjectItem(item, "operator"))
		{
			strcpy(operator, cJSON_GetObjectItem(item, "operator")->valuestring);
		}
		if (cJSON_GetObjectItem(item, "unit"))
		{
			strcpy(unit, cJSON_GetObjectItem(item, "unit")->valuestring);
		}
		if (cJSON_GetObjectItem(item, "duration"))
		{
			duration = cJSON_GetObjectItem(item, "duration")->valueint;
		}
		if (cJSON_GetObjectItem(item, "count"))
		{
			count = cJSON_GetObjectItem(item, "count")->valueint;
		}
		if (cJSON_HasObjectItem(item, "ruleValueRemark"))
		{
			if (cJSON_GetObjectItem(item, "ruleValueRemark"))
			{
				memset(ruleValueRemark, 0, sizeof(ruleValueRemark));
				strcpy(ruleValueRemark, cJSON_GetObjectItem(item, "ruleValueRemark")->valuestring);
				dzlog_info("security_rule_proc 123123 ruleValueRemark[%s]", ruleValueRemark);
			}
		}

		int repetRule = 0;
		if (strcmp(action, "DEL") == 0)
		{
			repetRule = 0;
			for (int i = 0; i < g_st_security_rule_num; i++)
			{
				// 如果现有规则有重复的，不删除数组对象，只是修改action为DEL
				if (strcmp(g_st_security_rule[i].indicator, indicator) == 0)
				{
					if (g_st_security_rule[i].ruleValueRemark != NULL && strlen(g_st_security_rule[i].ruleValueRemark) > 0)
					{
						if (ruleValueRemark != NULL && strlen(ruleValueRemark) > 0)
						{
							if (strcmp(g_st_security_rule[i].ruleValueRemark, ruleValueRemark) != 0)
							{
								continue;//不匹配时则直接下一个循环
							}
						}
					}
					else
					{
						if (ruleValueRemark == NULL || strlen(ruleValueRemark) == 0)
						{
							if (strcmp(g_st_security_rule[i].indicator, indicator) != 0)
							{
								continue;//不匹配时则直接下一个循环
							}
						}
					}
					if(strlen(ruleId) > 0)
					{
						strcpy(g_st_security_rule[i].ruleId, ruleId);
						sprintf(tmp, "%s:ruleid", g_rule_text[i]);
						iniparser_set(ini, tmp, ruleId);
					}
					strcpy(g_st_security_rule[i].action, "DEL");
					sprintf(tmp, "%s:action", g_rule_text[i]);
					iniparser_set(ini, tmp, "DEL");

					g_st_security_rule[i].ruleType = 2;
					sprintf(tmp, "%s:ruleType", g_rule_text[i]);
					char value[16]="2";
					iniparser_set(ini, tmp, value);
				}
			}
		}

		if (strcmp(action, "ADD") == 0)
		{
			for (int ii = 0; ii < 20; ii++)
			{
				memset(g_diskIndi[ii].partition, 0, 128);//当ADD的时候为什么清空？
			}
			repetRule = 0;
			int i = 0;
			for (i = 0; i < g_st_security_rule_num; i++)// 如果现有规则有重复的，则进行覆盖
			{
				g_st_security_rule[i].isAlarm = 2;
				g_st_security_rule[i].ruleType = 2;
				bool is_duplicate = false;
				if (strcmp(g_st_security_rule[i].indicator, indicator) == 0)
				{
					if (g_st_security_rule[i].ruleValueRemark != NULL && strlen(g_st_security_rule[i].ruleValueRemark) > 0)
					{
						if (ruleValueRemark != NULL && strlen(ruleValueRemark) > 0)
						{
							if (strcmp(g_st_security_rule[i].ruleValueRemark, ruleValueRemark) == 0)
							{
								is_duplicate = true;
							}
						}
					}
					else
					{
						if (ruleValueRemark == NULL || strlen(ruleValueRemark) == 0)
						{
							if (strcmp(g_st_security_rule[i].indicator, indicator) == 0)
							{
								is_duplicate = true;
							}
						}
					}
				}
				if (is_duplicate)
				{
					repetRule = 1;
					g_st_security_rule[i].isAlarm = 2;

					if (g_st_security_rule[i].ruleValueRemark != NULL && strlen(g_st_security_rule[i].ruleValueRemark) > 0)//先通过新字段进行区分先，不动原来的代码
					{
						//新磁盘分区告警   
						if (strlen(ruleId) > 0)
						{
							strcpy(g_st_security_rule[i].ruleId, ruleId);
							sprintf(tmp, "%s%s:ruleid", "mqtt_alarm_rule_disk_", ruleValueRemark);
							iniparser_set(ini, tmp, ruleId);
						}
						if (strlen(action) > 0)
						{
							strcpy(g_st_security_rule[i].action, action);
							sprintf(tmp, "%s%s:action", "mqtt_alarm_rule_disk_", ruleValueRemark);
							iniparser_set(ini, tmp, action);
						}
						if (strlen(indicator) > 0)
						{
							strcpy(g_st_security_rule[i].indicator, indicator);
							sprintf(tmp, "%s%s:indicator", "mqtt_alarm_rule_disk_", ruleValueRemark);
							iniparser_set(ini, tmp, indicator);
						}
						if (strlen(severity) > 0)
						{
							strcpy(g_st_security_rule[i].severity, severity);
							sprintf(tmp, "%s%s:severity", "mqtt_alarm_rule_disk_", ruleValueRemark);
							iniparser_set(ini, tmp, severity);
						}
						if (threshold != 0)
						{
							char value[16] = { 0 };
							g_st_security_rule[i].threshold = threshold;
							sprintf(tmp, "%s%s:threshold", "mqtt_alarm_rule_disk_", ruleValueRemark);
							sprintf(value, "%d", threshold);
							iniparser_set(ini, tmp, value);
						}
						if (strlen(operator) > 0)
						{
							strcpy(g_st_security_rule[i].operator, operator);
							sprintf(tmp, "%s%s:operator", "mqtt_alarm_rule_disk_", ruleValueRemark);
							iniparser_set(ini, tmp, operator);
						}
						if (strlen(unit) > 0)
						{
							strcpy(g_st_security_rule[i].unit, unit);
							sprintf(tmp, "%s%s:unit", "mqtt_alarm_rule_disk_", ruleValueRemark);
							iniparser_set(ini, tmp, unit);
						}
						if (duration != 0)
						{
							char value[16] = { 0 };
							g_st_security_rule[i].duration = duration;
							sprintf(tmp, "%s%s:duration", "mqtt_alarm_rule_disk_", ruleValueRemark);
							sprintf(value, "%d", duration);
							iniparser_set(ini, tmp, value);
						}
						if (count != 0)
						{
							char value[16] = { 0 };
							g_st_security_rule[i].count = count;
							sprintf(tmp, "%s%s:count", "mqtt_alarm_rule_disk_", ruleValueRemark);
							sprintf(value, "%d", count);
							iniparser_set(ini, tmp, value);
						}
						{
							char value[16] = { 0 };
							g_st_security_rule[i].ruleType = 2;
							sprintf(tmp, "%s%s:ruleType", "mqtt_alarm_rule_disk_", ruleValueRemark);
							sprintf(value, "%d", 2);
							iniparser_set(ini, tmp, value);
						}
					}
					else
					{
						if (strlen(ruleId) > 0)
						{
							strcpy(g_st_security_rule[i].ruleId, ruleId);
							sprintf(tmp, "%s:ruleid", g_rule_text[i]);
							iniparser_set(ini, tmp, ruleId);
						}
						if (strlen(action) > 0)
						{
							strcpy(g_st_security_rule[i].action, action);
							sprintf(tmp, "%s:action", g_rule_text[i]);
							iniparser_set(ini, tmp, action);
						}
						if (strlen(indicator) > 0)
						{
							strcpy(g_st_security_rule[i].indicator, indicator);
							sprintf(tmp, "%s:indicator", g_rule_text[i]);
							iniparser_set(ini, tmp, indicator);
						}
						if (strlen(severity) > 0)
						{
							strcpy(g_st_security_rule[i].severity, severity);
							sprintf(tmp, "%s:severity", g_rule_text[i]);
							iniparser_set(ini, tmp, severity);
						}
						if (threshold != 0)
						{
							char value[16] = { 0 };
							g_st_security_rule[i].threshold = threshold;
							sprintf(tmp, "%s:threshold", g_rule_text[i]);
							sprintf(value, "%d", threshold);
							iniparser_set(ini, tmp, value);
						}
						if (strlen(operator) > 0)
						{
							strcpy(g_st_security_rule[i].operator, operator);
							sprintf(tmp, "%s:operator", g_rule_text[i]);
							iniparser_set(ini, tmp, operator);
						}
						if (strlen(unit) > 0)
						{
							strcpy(g_st_security_rule[i].unit, unit);
							sprintf(tmp, "%s:unit", g_rule_text[i]);
							iniparser_set(ini, tmp, unit);
						}
						if (duration != 0)
						{
							char value[16] = { 0 };
							g_st_security_rule[i].duration = duration;
							sprintf(tmp, "%s:duration", g_rule_text[i]);
							sprintf(value, "%d", duration);
							iniparser_set(ini, tmp, value);
						}
						if (count != 0)
						{
							char value[16] = { 0 };
							g_st_security_rule[i].count = count;
							sprintf(tmp, "%s:count", g_rule_text[i]);
							sprintf(value, "%d", count);
							iniparser_set(ini, tmp, value);
						}
						{
							char value[16] = { 0 };
							g_st_security_rule[i].ruleType = 2;
							sprintf(tmp, "%s:ruleType", g_rule_text[i]);
							sprintf(value, "%d", 2);
							iniparser_set(ini, tmp, value);
						}
					}
					
				}
			}
			if (repetRule == 0)
			{
				dzlog_info("security_rule_proc start 71");
				if (ruleValueRemark != NULL && strlen(ruleValueRemark) > 0)
				{
					dzlog_info("security_rule_proc start 8");
					snprintf(tmp, sizeof(tmp), "%s%s", "mqtt_alarm_rule_disk_", ruleValueRemark);
					iniparser_set(ini, tmp, NULL); // 创建section
					dzlog_info("security_rule_proc start 81");
					//新增更新到缓存
					g_st_security_rule[g_st_security_rule_num].isAlarm = 2;
					g_st_security_rule[g_st_security_rule_num].ruleType = 2;
					dzlog_info("security_rule_proc start 9");

					//更新到ini
					//新磁盘分区告警   
					if (strlen(ruleId) > 0)
					{
						dzlog_info("security_rule_proc start 11");
						strcpy(g_st_security_rule[g_st_security_rule_num].ruleId, ruleId);
						snprintf(tmp, sizeof(tmp), "%s%s:ruleid", "mqtt_alarm_rule_disk_", ruleValueRemark);
						iniparser_set(ini, tmp, ruleId);
					}
					strcpy(g_st_security_rule[g_st_security_rule_num].ruleValueRemark, ruleValueRemark);
					snprintf(tmp, sizeof(tmp), "%s%s:ruleValueRemark", "mqtt_alarm_rule_disk_", ruleValueRemark);
					iniparser_set(ini, tmp, ruleValueRemark);
					dzlog_info("security_rule_proc start 10tmp[%s]", tmp);
					if (strlen(action) > 0)
					{
						dzlog_info("security_rule_proc start 12");
						strcpy(g_st_security_rule[g_st_security_rule_num].action, action);
						snprintf(tmp, sizeof(tmp), "%s%s:action", "mqtt_alarm_rule_disk_", ruleValueRemark);
						iniparser_set(ini, tmp, action);
					}
					if (strlen(indicator) > 0)
					{
						dzlog_info("security_rule_proc start 13");
						strcpy(g_st_security_rule[g_st_security_rule_num].indicator, indicator);
						snprintf(tmp, sizeof(tmp), "%s%s:indicator", "mqtt_alarm_rule_disk_", ruleValueRemark);
						iniparser_set(ini, tmp, indicator);
					}
					if (strlen(severity) > 0)
					{
						dzlog_info("security_rule_proc start 14");
						strcpy(g_st_security_rule[g_st_security_rule_num].severity, severity);
						snprintf(tmp, sizeof(tmp), "%s%s:severity", "mqtt_alarm_rule_disk_", ruleValueRemark);
						iniparser_set(ini, tmp, severity);
					}
					if (threshold != 0)
					{
						dzlog_info("security_rule_proc start 15");
						char value[16] = { 0 };
						g_st_security_rule[g_st_security_rule_num].threshold = threshold;
						snprintf(tmp, sizeof(tmp), "%s%s:threshold", "mqtt_alarm_rule_disk_", ruleValueRemark);
						snprintf(value, sizeof(value), "%d", threshold);
						iniparser_set(ini, tmp, value);
					}
					if (strlen(operator) > 0)
					{
						dzlog_info("security_rule_proc start 16");
						strcpy(g_st_security_rule[g_st_security_rule_num].operator, operator);
						snprintf(tmp, sizeof(tmp), "%s%s:operator", "mqtt_alarm_rule_disk_", ruleValueRemark);
						iniparser_set(ini, tmp, operator);
					}
					if (strlen(unit) > 0)
					{
						dzlog_info("security_rule_proc start 17");
						strcpy(g_st_security_rule[g_st_security_rule_num].unit, unit);
						snprintf(tmp, sizeof(tmp), "%s%s:unit", "mqtt_alarm_rule_disk_", ruleValueRemark);
						iniparser_set(ini, tmp, unit);
					}
					if (duration != 0)
					{
						dzlog_info("security_rule_proc start 18");
						char value[16] = { 0 };
						g_st_security_rule[g_st_security_rule_num].duration = duration;
						snprintf(tmp, sizeof(tmp), "%s%s:duration", "mqtt_alarm_rule_disk_", ruleValueRemark);
						snprintf(value, sizeof(value), "%d", duration);
						iniparser_set(ini, tmp, value);
					}
					if (count != 0)
					{
						dzlog_info("security_rule_proc start 19");
						char value[16] = { 0 };
						g_st_security_rule[g_st_security_rule_num].count = count;
						snprintf(tmp, sizeof(tmp), "%s%s:count", "mqtt_alarm_rule_disk_", ruleValueRemark);
						snprintf(value, sizeof(value), "%d", count);
						iniparser_set(ini, tmp, value);
					}
					{
						
						char value[16] = { 0 };
						g_st_security_rule[g_st_security_rule_num].ruleType = 2;
						snprintf(tmp, sizeof(tmp), "%s%s:ruleType", "mqtt_alarm_rule_disk_", ruleValueRemark);
						snprintf(value, sizeof(value), "%d", 2);
						iniparser_set(ini, tmp, value);
						dzlog_info("security_rule_proc start 20");
					}


				}
				else
				{
					g_st_security_rule[g_st_security_rule_num].isAlarm = 2;
					g_st_security_rule[g_st_security_rule_num].ruleType = 2;
					strcpy(g_st_security_rule[g_st_security_rule_num].ruleId, ruleId);
					strcpy(g_st_security_rule[g_st_security_rule_num].action, action);
					strcpy(g_st_security_rule[g_st_security_rule_num].indicator, indicator);
					strcpy(g_st_security_rule[g_st_security_rule_num].severity, severity);
					g_st_security_rule[g_st_security_rule_num].threshold = threshold;
					strcpy(g_st_security_rule[g_st_security_rule_num].operator, operator);
					strcpy(g_st_security_rule[g_st_security_rule_num].unit, unit);
					if (ruleValueRemark != NULL && strlen(ruleValueRemark) > 0)
					{
						strcpy(g_st_security_rule[g_st_security_rule_num].ruleValueRemark, ruleValueRemark);
					}
				}
				
				g_st_security_rule_num++;
			}
		}
	}
	dzlog_info("security_rule_proc start 72g_st_security_rule[6].threshold[%d]", g_st_security_rule[6].threshold);
	
	FILE *ini_file = fopen(rule_ini, "w");
	if (ini_file)
	{
		iniparser_dump_ini(ini, ini_file);
		fclose(ini_file);

	}

	// 增加返回200
	cJSON *json2 = NULL;
	json2 = cJSON_CreateObject();
	if (json2)
	{
		char uuid[64] = {0};
		GF_GetGUID(uuid);
		cJSON_AddStringToObject(json2, "mid", uuid);
		cJSON_AddNumberToObject(json2, "code", 200);
		cJSON_AddStringToObject(json2, "replyId", mid);
		cJSON_AddStringToObject(json2, "zone", zone);
		cJSON_AddStringToObject(json2, "node", node);
		cJSON_AddStringToObject(json2, "deviceId", deviceSn);
		cJSON_AddStringToObject(json2, "deviceSn", deviceSn);
		char cTime[128] = {0};
		int ret = systemDate2(cTime);
		cJSON_AddStringToObject(json2, "msgTime", cTime);

		char *pcJsonRes = NULL;
		pcJsonRes = cJSON_PrintUnformatted(json2);
		ret = IOTA_SendMqtt("/v1/devices/security/response", pcJsonRes, strlen(pcJsonRes));
		if (ret < 0)
			dzlog_error("terminalSyncTime sendMsg erro ret[%d]", ret);
		cJSON_Delete(json2);
		free(pcJsonRes);
	}

	cJSON_Delete(json);
	iniparser_freedict(ini);

	return 0;
}

void security_proc(char *pcJson)
{
	// dzlog_info("security_proc in ......");
	cJSON *json = NULL;
	char cmd[32] = {0};
	json = cJSON_Parse(pcJson);
	if (json)
	{
		strncpy(cmd, cJSON_GetObjectItem(json, "cmd")->valuestring, sizeof(cmd));
		// dzlog_info("security_proc cmd[%s] ", cmd);
		// 告警规则
		if (strstr(cmd, "setAlarmThresholdConfig"))
			security_rule_proc(pcJson);

		cJSON_Delete(json);
	}
}

void cpuUsage_publish(char *cpuUsageStr, int i)
{

	cJSON *json = NULL;
	cJSON *data = NULL;
	cJSON *params = NULL;
	cJSON *service = NULL;
	cJSON *services = NULL;
	cJSON *dev = NULL;
	cJSON *devs = NULL;
	char *pcJson = NULL;

	// 组包
	json = cJSON_CreateObject();
	if (json)
	{
		cJSON_AddItemToObject(json, "devices", devs = cJSON_CreateArray());
		cJSON_AddItemToArray(devs, dev = cJSON_CreateObject());

		cJSON_AddStringToObject(dev, "deviceSn", g_mqtt_ob.clientInfo.device_id);
		cJSON_AddItemToObject(dev, "services", services = cJSON_CreateArray());
		cJSON_AddItemToArray(services, service = cJSON_CreateObject());

		cJSON_AddStringToObject(service, "service", "usageOverLimitAlarm");
		char uuid[64] = {0};
		GF_GetGUID(uuid);
		cJSON_AddStringToObject(service, "mid", uuid); // 主动上报的，没有MID

		cJSON_AddItemToObject(service, "data", data = cJSON_CreateObject());
		cJSON_AddStringToObject(data, "eventType", "cpuUsage");
		cJSON_AddStringToObject(data, "qualifier", "rising");
		cJSON_AddNumberToObject(data, "indication", 1);
		cJSON_AddStringToObject(data, "severity", g_st_security_rule[i].severity);

		cJSON_AddItemToObject(data, "params", params = cJSON_CreateObject());
		cJSON_AddStringToObject(data, "ruleId", g_st_security_rule[i].ruleId);
		cJSON_AddStringToObject(data, "cpuUsage", cpuUsageStr);
		char *cpuUsageThresholdStr[8];
		sprintf(cpuUsageThresholdStr, "%d%", g_st_security_rule[i].threshold);
		cJSON_AddStringToObject(data, "cpuUsageThreshold", cpuUsageThresholdStr);
		// char t[32] = {0};
		// IOTA_getLocalTime(t);
		char cTime[128] = {0};
		int ret = systemDate(cTime);
		cJSON_AddStringToObject(service, "eventTime", cTime);

		{
			pcJson = cJSON_PrintUnformatted(json);
		}

		cJSON_Delete(json);
	}

	publishMessage(TOPIC_SECURITY, pcJson);
	free(pcJson);
}

cJSON *setData_cpuTemp(char *cpuTempStr, int i, char *eventType, char *qualifierStr, int num)
{
	cJSON *params = NULL;
	cJSON *data = cJSON_CreateObject();

	cJSON_AddStringToObject(data, "eventType", eventType);
	cJSON_AddStringToObject(data, "qualifier", qualifierStr);
	cJSON_AddNumberToObject(data, "indication", num);
	cJSON_AddStringToObject(data, "severity", g_st_security_rule[i].severity);

	cJSON_AddItemToObject(data, "params", params = cJSON_CreateObject());
	cJSON_AddStringToObject(params, "ruleId", g_st_security_rule[i].ruleId);
	cJSON_AddStringToObject(params, "cpuTemp", cpuTempStr);
	char *cpuUsageThresholdStr[8];
	sprintf(cpuUsageThresholdStr, "%d%", g_st_security_rule[i].threshold);
	cJSON_AddStringToObject(params, "cpuTempThreshold", cpuUsageThresholdStr);

	// char *pcJson = cJSON_PrintUnformatted(data);
	////dzlog_info("setData_cpuTemp pcJson[%s]", pcJson);
	cJSON_AddNumberToObject(params, "ruleType", g_st_security_rule[i].ruleType);
	return data;
}

cJSON *setData_NetCable(char *NetName, int i, char *eventType)
{
	cJSON *params = NULL;
	cJSON *data = cJSON_CreateObject();

	cJSON_AddStringToObject(data, "eventType", eventType);
	cJSON_AddNumberToObject(data, "indication", 1);
	cJSON_AddStringToObject(data, "severity", g_st_security_rule[i].severity);

	cJSON_AddItemToObject(data, "params", params = cJSON_CreateObject());
	cJSON_AddStringToObject(params, "name", NetName);
	cJSON_AddNumberToObject(params, "ruleType", g_st_security_rule[i].ruleType);
	return data;
}

cJSON *setData_netlinkDelay(char *target, int i, char *eventType, int target_port, char *protocol, int avgDelay)
{
	cJSON *params = NULL;
	cJSON *data = cJSON_CreateObject();

	cJSON_AddStringToObject(data, "eventType", eventType);
	cJSON_AddNumberToObject(data, "indication", 1);
	cJSON_AddStringToObject(data, "severity", g_st_security_rule[i].severity);

	cJSON_AddItemToObject(data, "params", params = cJSON_CreateObject());
	cJSON_AddStringToObject(params, "target", target);
	cJSON_AddNumberToObject(params, "target_port", target_port);
	cJSON_AddStringToObject(params, "protocol", protocol);
	cJSON_AddNumberToObject(params, "avgDelay", avgDelay);
	cJSON_AddNumberToObject(params, "delayThreshold", g_st_security_rule[i].threshold);
	cJSON_AddNumberToObject(params, "ruleType", g_st_security_rule[i].ruleType);
	return data;
}

cJSON *setData_netlinkBreak(char *target, int i, char *eventType, int target_port, char *protocol)
{
	cJSON *params = NULL;
	cJSON *data = cJSON_CreateObject();

	cJSON_AddStringToObject(data, "eventType", eventType);
	cJSON_AddNumberToObject(data, "indication", 1);
	cJSON_AddStringToObject(data, "severity", g_st_security_rule[i].severity);

	cJSON_AddItemToObject(data, "params", params = cJSON_CreateObject());
	cJSON_AddStringToObject(params, "target", target);
	cJSON_AddNumberToObject(params, "target_port", target_port);
	cJSON_AddStringToObject(params, "protocol", protocol);
	cJSON_AddNumberToObject(params, "ruleType", g_st_security_rule[i].ruleType);
	return data;
}

cJSON *setData_netlinkLossPacket(char *target, int i, char *eventType, int target_port, char *protocol, int avgLossPacket)
{
	cJSON *params = NULL;
	cJSON *data = cJSON_CreateObject();

	cJSON_AddStringToObject(data, "eventType", eventType);
	cJSON_AddNumberToObject(data, "indication", 1);
	cJSON_AddStringToObject(data, "severity", g_st_security_rule[i].severity);

	cJSON_AddItemToObject(data, "params", params = cJSON_CreateObject());
	cJSON_AddStringToObject(params, "target", target);
	cJSON_AddNumberToObject(params, "target_port", target_port);
	cJSON_AddStringToObject(params, "protocol", protocol);
	cJSON_AddNumberToObject(params, "avgLossPacket", avgLossPacket);
	cJSON_AddNumberToObject(params, "lossPacketThreshold", g_st_security_rule[i].threshold);
	cJSON_AddNumberToObject(params, "ruleType", g_st_security_rule[i].ruleType);
	return data;
}

cJSON *setData_cpuUsage(char *cpuUsageStr, int i, char *eventType, int num)
{
	// dzlog_info("------setData_Usage i[%d] eventType[%s], severity[%s]-----",i, eventType, g_st_security_rule[i].severity);
	cJSON *params = NULL;
	cJSON *data = cJSON_CreateObject();
	cJSON_AddStringToObject(data, "eventType", eventType);
	cJSON_AddStringToObject(data, "qualifier", "rising");
	cJSON_AddNumberToObject(data, "indication", num);
	cJSON_AddStringToObject(data, "severity", g_st_security_rule[i].severity);
	// params = cJSON_CreateObject();
	cJSON_AddItemToObject(data, "params", params = cJSON_CreateObject());
	cJSON_AddStringToObject(params, "ruleId", g_st_security_rule[i].ruleId);
	cJSON_AddStringToObject(params, "cpuUsage", cpuUsageStr);
	char *cpuUsageThresholdStr[8];
	sprintf(cpuUsageThresholdStr, "%d", g_st_security_rule[i].threshold);
	cJSON_AddStringToObject(params, "cpuUsageThreshold", cpuUsageThresholdStr);
	cJSON_AddNumberToObject(params, "ruleType", g_st_security_rule[i].ruleType);
	// dzlog_info("setData_Usage: %s", cJSON_PrintUnformatted(data));

	return data;
}

cJSON *setData_memUsage(char *memUsageStr, int i, char *eventType, int num)
{
	// dzlog_info("------setData_Usage i[%d] eventType[%s], severity[%s]-----",i, eventType, g_st_security_rule[i].severity);
	cJSON *params = NULL;
	cJSON *data = cJSON_CreateObject();
	cJSON_AddStringToObject(data, "eventType", eventType);
	cJSON_AddStringToObject(data, "qualifier", "rising");
	cJSON_AddNumberToObject(data, "indication", num);
	cJSON_AddStringToObject(data, "severity", g_st_security_rule[i].severity);
	// params = cJSON_CreateObject();
	cJSON_AddItemToObject(data, "params", params = cJSON_CreateObject());
	cJSON_AddStringToObject(params, "ruleId", g_st_security_rule[i].ruleId);
	cJSON_AddStringToObject(params, "memUsage", memUsageStr);
	char *memUsageThresholdStr[8];
	sprintf(memUsageThresholdStr, "%d", g_st_security_rule[i].threshold);
	cJSON_AddStringToObject(params, "memUsageThreshold", memUsageThresholdStr);
	// dzlog_info("setData_Usage: %s", cJSON_PrintUnformatted(data));
	cJSON_AddNumberToObject(params, "ruleType", g_st_security_rule[i].ruleType);
	return data;
}

cJSON *setData_diskUsage(char *diskUsageStr, int i, char *eventType, char *partition, int num, bool total_disk_flag)
{
	// dzlog_info("------setData_Usage i[%d] eventType[%s], severity[%s]-----",i, eventType, g_st_security_rule[i].severity);
	cJSON *params = NULL;
	cJSON *data = cJSON_CreateObject();
	cJSON_AddStringToObject(data, "eventType", eventType);
	if (total_disk_flag)
	{
		cJSON_AddStringToObject(data, "qualifier", "rising");
	}
	else
	{
		cJSON_AddStringToObject(data, "qualifier", "diskPartitionRising");
	}
	
	cJSON_AddNumberToObject(data, "indication", num);
	cJSON_AddStringToObject(data, "severity", g_st_security_rule[i].severity);
	// params = cJSON_CreateObject();
	cJSON_AddItemToObject(data, "params", params = cJSON_CreateObject());
	cJSON_AddStringToObject(params, "ruleId", g_st_security_rule[i].ruleId);
	cJSON_AddStringToObject(params, "diskUsage", diskUsageStr);
	if (!total_disk_flag)
	{
		cJSON_AddStringToObject(params, "partition", partition);
	}
	
	char *diskUsageThresholdStr[8];
	sprintf(diskUsageThresholdStr, "%d", g_st_security_rule[i].threshold);
	cJSON_AddStringToObject(params, "diskUsageThreshold", diskUsageThresholdStr);
	// dzlog_info("setData_Usage: %s", cJSON_PrintUnformatted(data));
	cJSON_AddNumberToObject(params, "ruleType", g_st_security_rule[i].ruleType);
	return data;
}

void alarm_publish(cJSON *data, char *serviceName)
{

	cJSON *json = NULL;
	cJSON *params = NULL;
	cJSON *service = NULL;
	cJSON *services = NULL;
	cJSON *dev = NULL;
	cJSON *devs = NULL;
	char *pcJson = NULL;

	// dzlog_info("----alarm_publish------");

	// 组包
	json = cJSON_CreateObject();
	if (json)
	{
		cJSON_AddItemToObject(json, "devices", devs = cJSON_CreateArray());
		cJSON_AddItemToArray(devs, dev = cJSON_CreateObject());
		cJSON_AddStringToObject(dev, "deviceSn", g_mqtt_ob.clientInfo.device_id);
		cJSON_AddItemToObject(dev, "services", services = cJSON_CreateArray());
		cJSON_AddItemToArray(services, service = cJSON_CreateObject());
		cJSON_AddStringToObject(service, "service", serviceName);
		char uuid[64] = {0};
		GF_GetGUID(uuid);
		cJSON_AddStringToObject(service, "mid", uuid); // 主动上报的，没有MID
		if (data)
			cJSON_AddItemToObject(service, "data", data);
		char t[128] = {0};
		systemDate2(t);
		cJSON_AddStringToObject(service, "eventTime", t);

		{
			pcJson = cJSON_PrintUnformatted(json);
		}
		// 这里释放会core，是否只释放总结点就可以了
		// cJSON_Delete(data);
		cJSON_Delete(json);
	}

	publishMessage(TOPIC_SECURITY, pcJson);
	free(pcJson);
}

void *net_check_thread(void *param)
{
	// dzlog_info("net_check_thread start...");

	pthread_detach(pthread_self());

	int fd, retval;
	char buf[BUFLEN] = {0};
	int len = BUFLEN;
	struct sockaddr_nl addr;
	struct nlmsghdr *nh;
	struct ifinfomsg *ifinfo;
	struct rtattr *attr;

	fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
	setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &len, sizeof(len));
	memset(&addr, 0, sizeof(addr));
	addr.nl_family = AF_NETLINK;
	addr.nl_groups = RTNLGRP_LINK;
	bind(fd, (struct sockaddr *)&addr, sizeof(addr));
	while ((retval = read(fd, buf, BUFLEN)) > 0)
	{
		// dzlog_info("net_check in ");
		// 确认网线插拔告警规则是否生效
		// if(!G_NET_CHECK_FLAG)

		//{
		//	continue;
		//}

		for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, retval); nh = NLMSG_NEXT(nh, retval))
		{
			if (nh->nlmsg_type == NLMSG_DONE)
				break;
			else if (nh->nlmsg_type == NLMSG_ERROR)
				return -1;
			else if (nh->nlmsg_type != RTM_NEWLINK)
				continue;
			ifinfo = NLMSG_DATA(nh);
			// dzlog_info("net_check %u: %s", ifinfo->ifi_index,  (ifinfo->ifi_flags & IFF_LOWER_UP) ? "up" : "down" );
			attr = (struct rtattr *)(((char *)nh) + NLMSG_SPACE(sizeof(*ifinfo)));
			len = nh->nlmsg_len - NLMSG_SPACE(sizeof(*ifinfo));
			for (; RTA_OK(attr, len); attr = RTA_NEXT(attr, len))
			{
				if (attr->rta_type == IFLA_IFNAME)
				{
					// dzlog_info("net_check net_name: %s", (char*)RTA_DATA(attr));
					break;
				}
			}
			memset(g_net_check_str, 0x00, sizeof(g_net_check_str));
			sprintf(g_net_check_str, "%s:%s", (ifinfo->ifi_flags & IFF_LOWER_UP) ? "up" : "down", (char *)RTA_DATA(attr));
			// dzlog_info("net_check info: %s", g_net_check_str);
		}

		sleep(1);
	}
}

void split(char *src, const char *separator, char **dest, int *num)
{
	char *token;
	char *rest = src;
	int count = 0;

	token = strtok_r(rest, separator, &rest);
	while (token != NULL)
	{
		dest[count] = strdup(token);
		count++;
		token = strtok_r(NULL, separator, &rest);
	}
	*num = count;
}

void split_data_free(char **dest, int num)
{
	int i = 0;
	for (i = 0; i < num; i++)
	{
		if (dest[i])
			free(dest[i]);
	}
}

double calculate_jitter(double delays[], int n)
{
	double sum = 0;

	for (int i = 0; i < n; i++)
	{
		sum += delays[i];
	}
	double mean = sum / n;

	double squared_diff_sum = 0;
	for (int i = 0; i < n; i++)
	{
		squared_diff_sum += pow(delays[i] - mean, 2);
	}

	double variance = squared_diff_sum / n;
	double standard_deviation = sqrt(variance);

	return standard_deviation;
}

int toAlarmFlag(int i)
{
	time_t currTime = time(NULL);
	
	if ((currTime - g_st_security_rule[i].lastCountTime) > g_st_security_rule[i].duration)
	{
		pthread_mutex_lock(&g_st_security_rule[i].lock);
		// g_st_security_rule[i].isAlarm = 0;
		g_st_security_rule[i].durationFlag=0;//下一个周期
		g_st_security_rule[i].lastCountTime = currTime;
		g_st_security_rule[i].currCount = 0;
		pthread_mutex_unlock(&g_st_security_rule[i].lock);
		return 2;
	}
	else
	{
		if (g_st_security_rule[i].currCount >= g_st_security_rule[i].count && g_st_security_rule[i].durationFlag==0)//周期内标志位
		{
			g_st_security_rule[i].durationFlag=1; //每个周期只告警一次，且两个周期互不影响
			return 1;
		}
		else
		{
			return 0;
		}
	}



	//if (g_st_security_rule[i].currCount >= g_st_security_rule[i].count)
	//{
	//	if ((currTime - g_st_security_rule[i].lastCountTime) > g_st_security_rule[i].duration)//超过统计周期，清空数据重新统计
	//	{
	//		pthread_mutex_lock(&g_st_security_rule[i].lock);
	//		g_st_security_rule[i].isAlarm = 0;
	//		g_st_security_rule[i].lastCountTime = currTime;
	//		g_st_security_rule[i].currCount = 0;
	//		pthread_mutex_unlock(&g_st_security_rule[i].lock);
	//		return 2;
	//	}
	//	else//周期内触发告警，返回1. 外层搭配g_st_security_rule[i].isAlarm决定是否上报
	//	{
	//		return 1;
	//	}
	//}
	//if (((currTime - g_st_security_rule[i].lastCountTime) > g_st_security_rule[i].duration) && (g_st_security_rule[i].currCount < g_st_security_rule[i].count))
	//{
	//	pthread_mutex_lock(&g_st_security_rule[i].lock);
	//	g_st_security_rule[i].lastCountTime = currTime;
	//	g_st_security_rule[i].currCount = 0;
	//	pthread_mutex_unlock(&g_st_security_rule[i].lock);
	//	return 2;
	//}

	return 0;
}

int check_delay(char *ip, int port, int delayMs)
{
	int sockfd;
	struct timeval tv1, tv2;

	// dzlog_info("check_delay ip[%s],port[%d],delayMs[%d]",ip,port,delayMs);

	// 创建TCP socket
	if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
	{
		dzlog_error("Failed to create socket");
		return -1;
	}

	struct timeval timeo = {0, delayMs * 1000};
	socklen_t len = sizeof(timeo);
	int ret = setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeo, len);
	if (ret)
	{
		dzlog_error("set socket opt failed!");
		close(sockfd);
		return -1;
	}

	// 连接到目标主机
	struct sockaddr_in serverAddr;
	memset(&serverAddr, '\0', sizeof(serverAddr));
	serverAddr.sin_family = AF_INET;
	serverAddr.sin_port = htons(port);
	inet_pton(AF_INET, ip, &(serverAddr.sin_addr));

	gettimeofday(&tv1, NULL);
	// dzlog_info("check_delay befor connect tv_sec[%lu] tv_usec[%lu]", tv1.tv_sec, tv1.tv_usec);
	connect(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
	gettimeofday(&tv2, NULL);
	// dzlog_info("check_delay after connect tv_sec[%lu] tv_usec[%lu]", tv2.tv_sec, tv2.tv_usec);

	int delay = (tv2.tv_sec - tv1.tv_sec) * 1000 + (tv2.tv_usec - tv1.tv_usec) / 1000;
	// dzlog_info("Delay with ip[%s] port[%d] is %d ms\n", ip,port,delay);

	close(sockfd);

	return delay;
}

int to_time(char *date_str, char *pcLocalTime, char *format)
{
	int CtimeFlag = 1;
	// 定义日期字符串
	// char date_str[] = "2024 Thu Feb 1 13:45:38";

	// 定义tm结构体用于存储解析后的时间信息
	struct tm _tm = {0};
	// strptime(date_str, "%Y %a %b %d %H:%M:%S", &_tm);
	////dzlog_info("date_str[%s], format[%s]",date_str, format);
	strptime(date_str, format, &_tm);

	// 将解析后的时间信息转换为time_t格式
	time_t tt1 = mktime(&_tm);
	time_t tt2 = time(&tt2);
	// 3秒循环查一次，3秒内的操作上传(3秒内可能会错过)
	if ((tt2 - tt1 < 4) && (logPublishTime == 0))
	{
		CtimeFlag = 0;
		logPublishTime = tt1;
	}
	// dzlog_info("tt2[%ld], tt1[%ld], logPublishTime[%ld]",tt2, tt1, logPublishTime);
	if ((tt1 - logPublishTime > 0) && (logPublishTime > 0))
	{
		CtimeFlag = 0;
		logPublishTime = tt1;
	}
	/*
	// 打印time_t格式的时间信息
	//dzlog_info("time_t: %ld", (long)tt);

	//time_t tt;
	struct tm _tm;
	//tt = time(&tt);
	localtime_r(&tt, &_tm);
	*/
	snprintf(pcLocalTime, 31, ("%04d-%02d-%02dT%02d:%02d:%02d+8:00"), _tm.tm_year + 1900, _tm.tm_mon + 1, _tm.tm_mday, _tm.tm_hour, _tm.tm_min, _tm.tm_sec);

	return CtimeFlag;
}

void sys_log_publish_hmNvr()
{
	char loginTime[128] = {0};
	char user[32] = {0};
	char srcIp[32] = {0};
	int srcPort = 0;
	char dstIp[32] = {0};
	int dstPort = 0;
	char opTime[128] = {0};
	char cmd[128] = {0};
	char cmdOutput[1024] = {0};
	char loginTimeZ[128] = {0};
	char result[128] = {0};
	FILE *fp;
	int i = 0;
	char output[1024] = {0};

	// 2024-02-22T13:35:44.738175+08:00 tmp sshd[1866850]: Connection from 192.168.7.14 port 56057 on 192.168.7.220 port 35520 rdomain ""
	// 过滤系统日志文件获取本机Ip端口相关信息
	strcpy(cmd, "grep -a \"Connection from\" /var/log/auth.log | tail -n 1 | awk \'{ print $10,$12}\'");
	// dzlog_info("sys_log_publish_oe cmd1[%s]",cmd);
	fp = popen(cmd, "r");
	if (fp == NULL)
	{
		dzlog_error("cmd exec error");
		return;
	}
	if (!feof(fp) && (fgets(output, 1024, fp) != NULL))
	{
		// dzlog_info("fgets output[%s]",output);
		int num = 0;
		char *tmpStr[20] = {0};
		split(output, " ", tmpStr, &num);
		// dzlog_info("split num[%d]",num);
		if (num == 2)
		{
			strcpy(dstIp, tmpStr[0]);
			dstPort = atoi(tmpStr[1]);
		}
		split_data_free(tmpStr, num);
	}
	pclose(fp);

	// 过滤系统日志文件获取相关信息
	{
		// strcpy(cmd, "grep -a \"Accepted password\" /userdata/log/syslog | tail -n 3");
		sprintf(cmd, "grep -a \"Accepted keyboard-interactive\" /var/log/auth.log | grep -v \"from %s\" | awk \'{ print $1,$9,$11}\' | tail -n 3", dstIp);
		// dzlog_info("sys_log_publish_oe cmd2[%s]", cmd);
		fp = popen(cmd, "r");
		if (fp == NULL)
		{
			dzlog_error("cmd exec error");
			return;
		}
		while (!feof(fp))
		{
			if (fgets(output, 1024, fp) != NULL)
			{
				// if(i >= 5)
				//	break;
				////dzlog_info("fgets output[%s]",output);
				int num = 0;
				char *tmpStr[20] = {0};
				split(output, " ", tmpStr, &num);
				////dzlog_info("split num[%d]",num);
				if (num != 3)
					continue;
				// 2024-02-19T16:16:17.999183+08:00 tmp sshd[506149]: Accepted password for admin from 192.168.7.14 port 54130 ssh2

				// sprintf(loginTime,"%s %s %s %s %s",tmpStr[4],tmpStr[0],tmpStr[1],tmpStr[2],tmpStr[3]);
				strcpy(loginTime, tmpStr[0]);
				strcpy(user, "root");
				strcpy(srcIp, tmpStr[1]);
				srcPort = atoi(tmpStr[2]);
				split_data_free(tmpStr, num);
				/*
				S_NETCARD sNetCard[100];
				int ret = wiredModules(sNetCard);
				//dzlog_info("sNetCard[0].ip[%s]",sNetCard[0].ip);
				//dzlog_info("sNetCard[1].ip[%s]",sNetCard[1].ip);
				if(ret > 0 )
				{
					strcpy(dstIp,sNetCard[0].ip);
				}
				else
				{
					strcpy(dstIp,"127.0.0.1");
				}*/

				// dstPort = 35520;
				sprintf(cmd, "ssh %s", dstIp);
				strcpy(cmdOutput, "Password auth succeeded");

				// dzlog_info("loginTime[%s] user[%s]srcIp[%s],srcPort[%d],dstIp[%s],dstPort[%d]", loginTime,user,srcIp,srcPort,dstIp,dstPort);

				int CTimeFlag = to_time(loginTime, loginTimeZ, "%Y-%m-%dT%H:%M:%S.%f%z");
				if (CTimeFlag)
				{
					////dzlog_info("sys_log_publish [%s] expeed time, continue... ",loginTimeZ);
					continue;
				}

				// 上报数据
				{
					cJSON *json = NULL;
					cJSON *params = NULL;
					cJSON *service = NULL;
					cJSON *services = NULL;
					cJSON *dev = NULL;
					cJSON *devs = NULL;
					char *pcJson = NULL;

					////dzlog_info("----sys_log_publish_oe------");

					// 组包
					json = cJSON_CreateObject();
					if (json)
					{
						cJSON_AddItemToObject(json, "devices", devs = cJSON_CreateArray());
						cJSON_AddItemToArray(devs, dev = cJSON_CreateObject());
						cJSON_AddStringToObject(dev, "deviceId", g_mqtt_ob.clientInfo.device_id);
						cJSON_AddStringToObject(dev, "deviceSn", g_mqtt_ob.clientInfo.device_id);
						cJSON_AddItemToObject(dev, "services", services = cJSON_CreateArray());
						cJSON_AddItemToArray(services, service = cJSON_CreateObject());
						cJSON_AddStringToObject(service, "service", "sshMonitor");
						char uuid[64] = {0};
						GF_GetGUID(uuid);
						cJSON_AddStringToObject(service, "mid", uuid);
						cJSON *data = cJSON_CreateObject();
						cJSON_AddStringToObject(data, "user", user);
						cJSON_AddStringToObject(data, "srcIp", srcIp);
						cJSON_AddNumberToObject(data, "srcPort", srcPort);
						cJSON_AddStringToObject(data, "dstIp", dstIp);
						cJSON_AddNumberToObject(data, "dstPort", dstPort);

						cJSON_AddStringToObject(data, "loginTime", loginTimeZ);
						cJSON_AddStringToObject(data, "opTime", loginTimeZ);
						cJSON_AddStringToObject(data, "cmd", cmd);
						cJSON_AddStringToObject(data, "cmdOutput", cmdOutput);
						cJSON_AddItemToObject(service, "data", data);
						char t[128] = {0};
						systemDate(t);
						cJSON_AddStringToObject(service, "eventTime", t);

						{
							pcJson = cJSON_PrintUnformatted(json);
						}
						cJSON_Delete(json);
					}

					publishMessage("/v1/devices/device/events", pcJson);
					free(pcJson);
				}
			}
			// i++;
		}
		pclose(fp);
	}
}

void sys_log_publish_oe_bak()
{
	char loginTime[128] = {0};
	char user[32] = {0};
	char srcIp[32] = {0};
	int srcPort = 0;
	char dstIp[32] = {0};
	int dstPort = 0;
	char opTime[128] = {0};
	char cmd[128] = {0};
	char cmdOutput[1024] = {0};
	char loginTimeZ[128] = {0};
	char result[128] = {0};
	FILE *fp;
	int i = 0;
	char output[1024] = {0};

	struct stat st = {0};
	if (stat("/userdata/log/syslog", &st) == -1)
	{
		return;
	}

	// 2024-02-22T13:35:44.738175+08:00 tmp sshd[1866850]: Connection from 192.168.7.14 port 56057 on 192.168.7.220 port 35520 rdomain ""
	// 过滤系统日志文件获取本机Ip端口相关信息
	strcpy(cmd, "grep -a \"Connection from\" /userdata/log/syslog | tail -n 1 | awk \'{ print $10,$12}\'");
	// dzlog_info("sys_log_publish_oe cmd1[%s]",cmd);
	fp = popen(cmd, "r");
	if (fp == NULL)
	{
		dzlog_error("cmd exec error");
		return;
	}
	if (!feof(fp) && (fgets(output, 1024, fp) != NULL))
	{
		// dzlog_info("fgets output[%s]",output);
		int num = 0;
		char *tmpStr[20] = {0};
		split(output, " ", tmpStr, &num);
		// dzlog_info("split num[%d]",num);
		if (num == 2)
		{
			strcpy(dstIp, tmpStr[0]);
			dstPort = atoi(tmpStr[1]);
			// free(tmpStr[0]);
			// free(tmpStr[1]);
		}
		split_data_free(tmpStr, num);
	}
	pclose(fp);

	// 过滤系统日志文件获取相关信息
	{
		// strcpy(cmd, "grep -a \"Accepted password\" /userdata/log/syslog | tail -n 3");
		strcpy(cmd, "grep -a \"Connection from\" /userdata/log/syslog | awk \'{ print $1,$6,$8}\' | tail -n 3");
		// dzlog_info("sys_log_publish_oe cmd2[%s]", cmd);
		fp = popen(cmd, "r");
		if (fp == NULL)
		{
			dzlog_error("cmd exec error");
			return;
		}
		while (!feof(fp))
		{
			if (fgets(output, 1024, fp) != NULL)
			{
				// if(i >= 5)
				//	break;
				////dzlog_info("fgets output[%s]",output);
				int num = 0;
				char *tmpStr[20] = {0};
				split(output, " ", tmpStr, &num);
				////dzlog_info("split num[%d]",num);
				if (num != 3)
				{
					// dzlog_info("num != 3");
					split_data_free(tmpStr, num);
					continue;
				}
				// 2024-02-19T16:16:17.999183+08:00 tmp sshd[506149]: Accepted password for admin from 192.168.7.14 port 54130 ssh2

				// sprintf(loginTime,"%s %s %s %s %s",tmpStr[4],tmpStr[0],tmpStr[1],tmpStr[2],tmpStr[3]);
				strcpy(loginTime, tmpStr[0]);
				strcpy(user, "admin");
				strcpy(srcIp, tmpStr[1]);
				srcPort = atoi(tmpStr[2]);
				split_data_free(tmpStr, num);
				/*
				S_NETCARD sNetCard[100];
				int ret = wiredModules(sNetCard);
				//dzlog_info("sNetCard[0].ip[%s]",sNetCard[0].ip);
				//dzlog_info("sNetCard[1].ip[%s]",sNetCard[1].ip);
				if(ret > 0 )
				{
					strcpy(dstIp,sNetCard[0].ip);
				}
				else
				{
					strcpy(dstIp,"127.0.0.1");
				}*/

				// dstPort = 35520;
				sprintf(cmd, "ssh %s", dstIp);
				strcpy(cmdOutput, "Password auth succeeded");

				// dzlog_info("loginTime[%s] user[%s]srcIp[%s],srcPort[%d],dstIp[%s],dstPort[%d]", loginTime,user,srcIp,srcPort,dstIp,dstPort);

				int CTimeFlag = to_time(loginTime, loginTimeZ, "%Y-%m-%dT%H:%M:%S.%f%z");
				if (CTimeFlag)
				{
					////dzlog_info("sys_log_publish [%s] expeed time, continue... ",loginTimeZ);
					continue;
				}

				// 上报数据
				{
					cJSON *json = NULL;
					cJSON *params = NULL;
					cJSON *service = NULL;
					cJSON *services = NULL;
					cJSON *dev = NULL;
					cJSON *devs = NULL;
					char *pcJson = NULL;

					////dzlog_info("----sys_log_publish_oe------");

					// 组包
					json = cJSON_CreateObject();
					if (json)
					{
						cJSON_AddItemToObject(json, "devices", devs = cJSON_CreateArray());
						cJSON_AddItemToArray(devs, dev = cJSON_CreateObject());
						cJSON_AddStringToObject(dev, "deviceId", g_mqtt_ob.clientInfo.device_id);
						cJSON_AddStringToObject(dev, "deviceSn", g_mqtt_ob.clientInfo.device_id);
						cJSON_AddItemToObject(dev, "services", services = cJSON_CreateArray());
						cJSON_AddItemToArray(services, service = cJSON_CreateObject());
						cJSON_AddStringToObject(service, "service", "sshMonitor");
						char uuid[64] = {0};
						GF_GetGUID(uuid);
						cJSON_AddStringToObject(service, "mid", uuid);
						cJSON *data = cJSON_CreateObject();
						cJSON_AddStringToObject(data, "user", user);
						cJSON_AddStringToObject(data, "srcIp", srcIp);
						cJSON_AddNumberToObject(data, "srcPort", srcPort);
						cJSON_AddStringToObject(data, "dstIp", dstIp);
						cJSON_AddNumberToObject(data, "dstPort", dstPort);

						cJSON_AddStringToObject(data, "loginTime", loginTimeZ);
						cJSON_AddStringToObject(data, "opTime", loginTimeZ);
						cJSON_AddStringToObject(data, "cmd", cmd);
						cJSON_AddStringToObject(data, "cmdOutput", cmdOutput);
						cJSON_AddItemToObject(service, "data", data);
						char t[128] = {0};
						systemDate(t);
						cJSON_AddStringToObject(service, "eventTime", t);

						{
							pcJson = cJSON_PrintUnformatted(json);
						}
						cJSON_Delete(json);
					}

					publishMessage("/v1/devices/device/events", pcJson);
					free(pcJson);
				}
			}
			// i++;
		}
		pclose(fp);
	}
}

void sys_log_publish_oe()
{
	char loginTime[128] = {0};
	char user[32] = {0};
	char srcIp[32] = {0};
	int srcPort = 0;
	char dstIp[32] = {0};
	int dstPort = 0;
	char opTime[128] = {0};
	char cmd[128] = {0};
	char cmdOutput[1024] = {0};
	char loginTimeZ[128] = {0};
	char result[128] = {0};
	FILE *fp;
	int i = 0;
	char output[1024] = {0};

	struct stat st = {0};
	if (stat("/userdata/log/syslog", &st) == -1)
	{
		return;
	}

	// 2024-02-22T13:35:44.738175+08:00 tmp sshd[1866850]: Connection from 192.168.7.14 port 56057 on 192.168.7.220 port 35520 rdomain ""
	// 过滤系统日志文件获取本机Ip端口相关信息
	strcpy(cmd, "grep -a \"Connection from\" /userdata/log/syslog | tail -n 1 | awk \'{ print $10,$12}\'");
	// dzlog_info("sys_log_publish_oe cmd1[%s]",cmd);
	fp = popen(cmd, "r");
	if (fp == NULL)
	{
		dzlog_error("cmd exec error");
		return;
	}
	if (!feof(fp) && (fgets(output, 1024, fp) != NULL))
	{
		// dzlog_info("fgets output[%s]",output);
		int num = 0;
		char *tmpStr[20] = {0};
		split(output, " ", tmpStr, &num);
		// dzlog_info("split num[%d]",num);
		if (num == 2)
		{
			strcpy(dstIp, tmpStr[0]);
			dstPort = atoi(tmpStr[1]);
		}
		split_data_free(tmpStr, num);
	}
	pclose(fp);

	// 过滤系统日志文件获取相关信息
	{
		struct stat st = {0};
		if (stat("/userdata/log/syslog", &st) == -1)
		{
			return;
		}

		strcpy(cmd, "grep -a \"Accepted password\" /userdata/log/syslog | tail -n 3");
		// dzlog_info("sys_log_publish_oe cmd2[%s]",cmd);
		fp = popen(cmd, "r");
		if (fp == NULL)
		{
			dzlog_error("cmd exec error");
			return;
		}
		while (!feof(fp))
		{
			if (fgets(output, 1024, fp) != NULL)
			{
				// if(i >= 5)
				//	break;
				////dzlog_info("fgets output[%s]",output);
				int num = 0;
				char *tmpStr[20] = {0};
				split(output, " ", tmpStr, &num);
				////dzlog_info("split num[%d]",num);
				if (num != 12)
				{
					split_data_free(tmpStr, num);
					continue;
				}
				// 2024-02-19T16:16:17.999183+08:00 tmp sshd[506149]: Accepted password for admin from 192.168.7.14 port 54130 ssh2

				// sprintf(loginTime,"%s %s %s %s %s",tmpStr[4],tmpStr[0],tmpStr[1],tmpStr[2],tmpStr[3]);
				strcpy(loginTime, tmpStr[0]);
				strcpy(user, tmpStr[6]);
				strcpy(srcIp, tmpStr[8]);
				srcPort = atoi(tmpStr[10]);
				split_data_free(tmpStr, num);
				/*
				S_NETCARD sNetCard[100];
				int ret = wiredModules(sNetCard);
				//dzlog_info("sNetCard[0].ip[%s]",sNetCard[0].ip);
				//dzlog_info("sNetCard[1].ip[%s]",sNetCard[1].ip);
				if(ret > 0 )
				{
					strcpy(dstIp,sNetCard[0].ip);
				}
				else
				{
					strcpy(dstIp,"127.0.0.1");
				}*/

				// dstPort = 35520;
				sprintf(cmd, "ssh %s", dstIp);
				strcpy(cmdOutput, "Password auth succeeded");

				// dzlog_info("loginTime[%s] user[%s]srcIp[%s],srcPort[%d],dstIp[%s],dstPort[%d]", loginTime,user,srcIp,srcPort,dstIp,dstPort);

				int CTimeFlag = to_time(loginTime, loginTimeZ, "%Y-%m-%dT%H:%M:%S.%f%z");
				if (CTimeFlag)
				{
					////dzlog_info("sys_log_publish [%s] expeed time, continue... ",loginTimeZ);
					continue;
				}

				// 上报数据
				{
					cJSON *json = NULL;
					cJSON *params = NULL;
					cJSON *service = NULL;
					cJSON *services = NULL;
					cJSON *dev = NULL;
					cJSON *devs = NULL;
					char *pcJson = NULL;

					////dzlog_info("----sys_log_publish_oe------");

					// 组包
					json = cJSON_CreateObject();
					if (json)
					{
						cJSON_AddItemToObject(json, "devices", devs = cJSON_CreateArray());
						cJSON_AddItemToArray(devs, dev = cJSON_CreateObject());
						cJSON_AddStringToObject(dev, "deviceId", g_mqtt_ob.clientInfo.device_id);
						cJSON_AddStringToObject(dev, "deviceSn", g_mqtt_ob.clientInfo.device_id);
						cJSON_AddItemToObject(dev, "services", services = cJSON_CreateArray());
						cJSON_AddItemToArray(services, service = cJSON_CreateObject());
						cJSON_AddStringToObject(service, "service", "sshMonitor");
						char uuid[64] = {0};
						GF_GetGUID(uuid);
						cJSON_AddStringToObject(service, "mid", uuid);
						cJSON *data = cJSON_CreateObject();
						cJSON_AddStringToObject(data, "user", user);
						cJSON_AddStringToObject(data, "srcIp", srcIp);
						cJSON_AddNumberToObject(data, "srcPort", srcPort);
						cJSON_AddStringToObject(data, "dstIp", dstIp);
						cJSON_AddNumberToObject(data, "dstPort", dstPort);

						cJSON_AddStringToObject(data, "loginTime", loginTimeZ);
						cJSON_AddStringToObject(data, "opTime", loginTimeZ);
						cJSON_AddStringToObject(data, "cmd", cmd);
						cJSON_AddStringToObject(data, "cmdOutput", cmdOutput);
						cJSON_AddItemToObject(service, "data", data);
						char t[128] = {0};
						systemDate(t);
						cJSON_AddStringToObject(service, "eventTime", t);

						{
							pcJson = cJSON_PrintUnformatted(json);
						}
						cJSON_Delete(json);
					}

					publishMessage("/v1/devices/device/events", pcJson);
					free(pcJson);
				}
			}
			// i++;
		}
		pclose(fp);
	}
}

void sys_log_publish_x86()
{
	char loginTime[128] = {0};
	char user[32] = {0};
	char srcIp[32] = {0};
	int srcPort = 0;
	char dstIp[32] = {0};
	int dstPort = 22;
	char opTime[128] = {0};
	char cmd[128] = {0};
	char cmdOutput[1024] = {0};
	char loginTimeZ[128] = {0};

	// 获取本地ip

}

void sys_log_publish()
{
	char loginTime[128] = {0};
	char user[32] = {0};
	char srcIp[32] = {0};
	int srcPort = 0;
	char dstIp[32] = {0};
	int dstPort = 0;
	char opTime[128] = {0};
	char cmd[128] = {0};
	char cmdOutput[1024] = {0};
	char loginTimeZ[128] = {0};
	bool issyslogin = false;
	// 过滤系统日志文件获取相关信息
	{
		struct stat st = {0};
		if (stat("/userdata/log/syslogin.log", &st) != -1)
		{
			issyslogin = true;
		}
		else
		{
			if (stat("/var/log/message.log", &st) == -1)
			{
				return;
			}
		}

		char cmd[128] = {0};
		char result[128] = {0};
		FILE *fp;
		int i = 0;
		char output[1024] = {0};
		if (issyslogin)
		{
			strcpy(cmd, "grep -a \"Accepted password\" /userdata/log/syslogin.log | tail -n 3");
		}
		else
		{
			strcpy(cmd, "grep -r \"Password auth succeeded\" /var/log/message.log");
		}

		// dzlog_info("sys_log_publish cmd[%s]",cmd);
		fp = popen(cmd, "r");
		if (fp == NULL)
		{
			dzlog_error("cmd exec error");
			return;
		}
		while (!feof(fp))
		{
			if (fgets(output, 1024, fp) != NULL)
			{
				if (i >= 5)
					break;
				// dzlog_info("fgets output[%s]",output);
				int num = 0;
				char *tmpStr[20] = {0};
				split(output, " ", tmpStr, &num);
				// dzlog_info("split num[%d]",num);
				if (num != 14)
				{
					split_data_free(tmpStr, num);
					continue;
				}
				// Tue Jan 30 15:06:23 2024 authpriv.notice dropbear[5424]: Password auth succeeded for 'admin' from 192.168.7.131:62491

				sprintf(loginTime, "%s %s %s %s %s", tmpStr[4], tmpStr[0], tmpStr[1], tmpStr[2], tmpStr[3]);
				// user
				memcpy(user, tmpStr[11] + 1, strlen(tmpStr[11]) - 2);
				char ip_port_str[64] = {0};
				strcpy(ip_port_str, tmpStr[13]);
				split_data_free(tmpStr, num);
				// dzlog_info("ip_port_str[%s],tmpStr[13][%s]",ip_port_str,tmpStr[13]);
				int num2 = 0;
				char *tmpStr2[12] = {0};
				split(ip_port_str, ":", tmpStr2, &num2);
				if (num2 == 2)
				{
					strcpy(srcIp, tmpStr2[0]);
					srcPort = atoi(tmpStr2[1]);
				}
				split_data_free(tmpStr2, num2);
				S_NETCARD sNetCard[100];
				int ret = wiredModules(sNetCard);
				// dzlog_info("sNetCard[0].ip[%s]",sNetCard[0].ip);
				// dzlog_info("sNetCard[1].ip[%s]",sNetCard[1].ip);
				if (ret > 0)
				{
					strcpy(dstIp, sNetCard[1].ip);
				}
				else
				{
					strcpy(dstIp, "127.0.0.1");
				}
				// 暂时先写死
				// netstat -tulnp | grep dropbear | awk '/:/{print $4}' | cut -d: -f2
				dstPort = 35520;
				strcpy(opTime, loginTime);
				sprintf(cmd, "ssh %s", dstIp);
				strcpy(cmdOutput, "Password auth succeeded");

				// dzlog_info("loginTime[%s] user[%s]srcIp[%s],srcPort[%d],dstIp[%s]", loginTime,user,srcIp,srcPort,dstIp);

				int CTimeFlag = to_time(loginTime, loginTimeZ, "%Y %a %b %d %H:%M:%S");
				if (CTimeFlag)
				{
					// dzlog_info("sys_log_publish [%s] expeed time, continue... ",loginTimeZ);
					continue;
				}

				// 上报数据
				{
					cJSON *json = NULL;
					cJSON *params = NULL;
					cJSON *service = NULL;
					cJSON *services = NULL;
					cJSON *dev = NULL;
					cJSON *devs = NULL;
					char *pcJson = NULL;

					// dzlog_info("----sys_log_publish------");

					// 组包
					json = cJSON_CreateObject();
					if (json)
					{
						cJSON_AddItemToObject(json, "devices", devs = cJSON_CreateArray());
						cJSON_AddItemToArray(devs, dev = cJSON_CreateObject());
						cJSON_AddStringToObject(dev, "deviceId", g_mqtt_ob.clientInfo.device_id);
						cJSON_AddStringToObject(dev, "deviceSn", g_mqtt_ob.clientInfo.device_id);
						cJSON_AddItemToObject(dev, "services", services = cJSON_CreateArray());
						cJSON_AddItemToArray(services, service = cJSON_CreateObject());
						cJSON_AddStringToObject(service, "service", "sshMonitor");
						char uuid[64] = {0};
						GF_GetGUID(uuid);
						cJSON_AddStringToObject(service, "mid", uuid);
						cJSON *data = cJSON_CreateObject();
						cJSON_AddStringToObject(data, "user", user);
						cJSON_AddStringToObject(data, "srcIp", srcIp);
						cJSON_AddNumberToObject(data, "srcPort", srcPort);
						cJSON_AddStringToObject(data, "dstIp", dstIp);
						cJSON_AddNumberToObject(data, "dstPort", dstPort);

						cJSON_AddStringToObject(data, "loginTime", loginTimeZ);
						cJSON_AddStringToObject(data, "opTime", loginTimeZ);
						cJSON_AddStringToObject(data, "cmd", cmd);
						cJSON_AddStringToObject(data, "cmdOutput", cmdOutput);
						cJSON_AddItemToObject(service, "data", data);
						char t[128] = {0};
						systemDate(t);
						cJSON_AddStringToObject(service, "eventTime", t);

						{
							pcJson = cJSON_PrintUnformatted(json);
						}
						cJSON_Delete(json);
					}

					publishMessage("/v1/devices/device/events", pcJson);
					free(pcJson);
				}
			}
			i++;
		}
		pclose(fp);
	}
}

void *alarm_thread(void *param)
{
	pthread_detach(pthread_self());

	// 启动网卡检查线程
	netinterface_status netStatus[10];
	getNetPortStatus(netStatus, 10);

	// 每3秒轮询一次告警规则，获取相关事件判断是否触发报警
	while (1)
	{
		char result[64] = {0};
		getCpuUsage(result);
		g_sys_indicators.cpuUsage  = atoi(result);		
	
		getMemUsage(result);
		g_sys_indicators.memUsage = atoi(result);

		getCpuTemp(result);
		char* pos = strstr(result, "°C");
		if (pos != NULL) {
			*pos = '\0'; // 终止字符串在"°C"之前
		}
		g_sys_indicators.cpuTemp = atoi(result);
		// 欧拉系统的cpu文档是毫度为单位
		if (g_sys_indicators.cpuTemp > 1000)
			g_sys_indicators.cpuTemp = g_sys_indicators.cpuTemp / 1000;
		
		for (int i = 0; i < g_st_security_rule_num; i++)
		{
			// 如果action为ADD，说明当前规则有效
			if (strcmp(g_st_security_rule[i].action, "ADD") == 0)
			{
				// cpu使用率
				if (strcmp(g_st_security_rule[i].indicator, "cpuUsage") == 0)
				{
					char cpuUsageStr[16];
					sprintf(cpuUsageStr, "%d", g_sys_indicators.cpuUsage);
					if (g_sys_indicators.cpuUsage >= g_st_security_rule[i].threshold)
					{
						//超过阈值
						g_st_security_rule[i].currCount++;
						//并且大于上报的时间间隔duration,才会上报一次
						//cpu使用率超过阈值，并且超过的次数大于count才能上报
						//setAlarmThreshold会设置isAlarm为2，所以又会上报报警
						if (toAlarmFlag(i) == 1 && g_st_security_rule[i].isAlarm != 1)
						{
							g_st_security_rule[i].isAlarm = 1;
							cJSON *data = setData_cpuUsage(cpuUsageStr, i, "cpuUsage", 1);
							alarm_publish(data, ALARM_SERVICE_USAGE);
							//告警后 主动上报  功能暂废除
							// char uuid[64] = {0};
							// GF_GetGUID(uuid);
							// terminalcpuUsage(uuid, g_mqtt_ob.clientInfo.device_id);
						}
					}
					else
					{
						// if (g_st_security_rule[i].isAlarm != 0)
						if (toAlarmFlag(i) == 2 && g_st_security_rule[i].isAlarm != 0)
						{
							g_st_security_rule[i].isAlarm = 0;
							cJSON *data = setData_cpuUsage(cpuUsageStr, i, "cpuUsage", 0);
							alarm_publish(data, ALARM_SERVICE_USAGE);
						}
					}
				}
				// 内存使用率
				else if (strcmp(g_st_security_rule[i].indicator, "memUsage") == 0)
				{

					char memUsageStr[16];
					sprintf(memUsageStr, "%d", g_sys_indicators.memUsage);
					if (g_sys_indicators.memUsage >= g_st_security_rule[i].threshold)
					{
						g_st_security_rule[i].currCount++;
						if (toAlarmFlag(i) == 1 && g_st_security_rule[i].isAlarm != 1)
						{
							g_st_security_rule[i].isAlarm = 1;
							cJSON *data = setData_memUsage(memUsageStr, i, "memUsage", 1);
							alarm_publish(data, ALARM_SERVICE_USAGE);
							//告警后 主动上报 功能暂废除
							// char uuid[64] = {0};
							// GF_GetGUID(uuid);
							// terminalmemUsage(uuid, g_mqtt_ob.clientInfo.device_id);
						}
					}
					else
					{
						if (toAlarmFlag(i) == 2 && g_st_security_rule[i].isAlarm != 0)
						{
							g_st_security_rule[i].isAlarm = 0;
							cJSON *data = setData_memUsage(memUsageStr, i, "memUsage", 0);
							alarm_publish(data, ALARM_SERVICE_USAGE);
						}
					}
				}
				//先磁盘分区告警
				else if (g_st_security_rule[i].ruleValueRemark != NULL && strlen(g_st_security_rule[i].ruleValueRemark) > 0)
				{
					int jj = 0;
					time_t currTime = time(NULL);
					if (currTime - g_disk_data.currTime >= 15)
					{
						g_disk_data.currTime = time(NULL);
						S_DATA_REPORT_DISK dataReport_tmp[20];
						int ret = diskInfoReport(&dataReport_tmp);
						g_disk_data.count = ret;
						for (jj = 0; jj < ret; jj++) {
							strncpy(g_disk_data.disk_data[jj].mountedOn,dataReport_tmp[jj].mountedOn,sizeof(g_disk_data.disk_data[jj].mountedOn) - 1);
							g_disk_data.disk_data[jj].mountedOn[sizeof(g_disk_data.disk_data[jj].mountedOn) - 1] = '\0';
							g_disk_data.disk_data[jj].usedPercent = convert_string_to_double(dataReport_tmp[jj].usedPercent);
						}
					}
					for (jj = 0; jj < g_disk_data.count; jj++)
					{
						if (strcmp(g_disk_data.disk_data[jj].mountedOn, g_st_security_rule[i].ruleValueRemark) == 0)
						{
							if (g_disk_data.disk_data[jj].usedPercent >= g_st_security_rule[i].threshold)//大于阈值
							{
								g_st_security_rule[i].currCount++;
								if (toAlarmFlag(i) == 1 && g_st_security_rule[i].isAlarm != 1)
								{
									g_st_security_rule[i].isAlarm = 1;
									char diskUsageStr[16] = { 0 };
									sprintf(diskUsageStr, "%d", g_disk_data.disk_data[jj].usedPercent);
									cJSON* data = setData_diskUsage(diskUsageStr, i, "diskUsage", g_st_security_rule[i].ruleValueRemark, 1 , false);
									alarm_publish(data, ALARM_SERVICE_USAGE);
								}
							}
							else
							{
								if (toAlarmFlag(i) == 2 && g_st_security_rule[i].isAlarm != 0)
								{
									g_st_security_rule[i].isAlarm = 0;
									char diskUsageStr[16] = { 0 };
									sprintf(diskUsageStr, "%d", g_disk_data.disk_data[jj].usedPercent);
									cJSON* data = setData_diskUsage(diskUsageStr, i, "diskUsage", g_st_security_rule[i].ruleValueRemark, 0 , false);
									alarm_publish(data, ALARM_SERVICE_USAGE);
								}
							}
						}
					}
				}
				// 总磁盘使用率
				else if (strcmp(g_st_security_rule[i].indicator, "diskUsage") == 0)
				{
					// ST_DISK_INDICATORS diskIndi[20];
					// int diskCount = 0;
					// getDiskUsage(diskIndi, g_st_security_rule[i].threshold, &diskCount, i);
					float TotalDiskUsage = getTotalDiskUsage();
					//dzlog_debug("diskUsage TotalDiskUsage[%f]", TotalDiskUsage);
					if(TotalDiskUsage >= (float)g_st_security_rule[i].threshold )
					{
						// g_sys_indicators.diskUsage = diskUsage;
						// if(diskUsage > g_st_security_rule[i].threshold)
						if (/*toAlarmFlag(i)  && */ g_st_security_rule[i].isAlarm != 1)
						{
							g_st_security_rule[i].isAlarm = 1;
							// int diskNum = 0;
							// for (diskNum = 0; diskNum < diskCount; diskNum++)
							// {
							// 	// dzlog_info("diskCount2[%d]",diskCount);
							char diskUsageStr[16] = {0};
							sprintf(diskUsageStr, "%.2f", TotalDiskUsage);
							// 	cJSON *data = setData_diskUsage(diskUsageStr, i, "diskUsage", diskIndi[diskNum].partition);
							// 	alarm_publish(data, ALARM_SERVICE_USAGE);
							// }
							cJSON *data = setData_diskUsage(diskUsageStr, i, "diskUsage", NULL,1, true);
							alarm_publish(data, ALARM_SERVICE_USAGE);
							//告警后 主动上报 功能暂废除
							// char uuid[64] = {0};
							// GF_GetGUID(uuid);
							// terminaldiskUsage(uuid, g_mqtt_ob.clientInfo.device_id);						
						}
					}
				}
				// CPU温度
				else if (strcmp(g_st_security_rule[i].indicator, "cpuTemp") == 0)
				{
					char cpuTempStr[32] = {0};
					sprintf(cpuTempStr, "%d", g_sys_indicators.cpuTemp);

					char *qualifierStr;
					if (g_sys_indicators.cpuTemp >= g_st_security_rule[i].threshold)
					{
						g_st_security_rule[i].currCount++;
						if (toAlarmFlag(i) == 1 && g_st_security_rule[i].isAlarm != 1)
						{
							g_st_security_rule[i].isAlarm = 1;
							cJSON *data = setData_cpuTemp(cpuTempStr, i, "cpuTemp", "rising", 1);
							alarm_publish(data, ALARM_SERVICE_USAGE);
							//告警后 主动上报 功能暂废除
							// char uuid[64] = {0};
							// GF_GetGUID(uuid);
							// terminalcpuTemp(uuid, g_mqtt_ob.clientInfo.device_id);	
						}
					}
					else
					{
						if (toAlarmFlag(i) == 2 && g_st_security_rule[i].isAlarm != 0)
						{
							g_st_security_rule[i].isAlarm = 0;
							cJSON *data = setData_cpuTemp(cpuTempStr, i, "cpuTemp", "rising", 0);
							alarm_publish(data, ALARM_SERVICE_USAGE);
						}
					}
				}
				// 插入/拔出网线告警
				else if (strcmp(g_st_security_rule[i].indicator, "NetCableInsert") == 0)
				{

					/*

					if(strstr(g_net_check_str,"up"))
					{
						NetCableInsert = 1;
						strcpy(NetName, g_net_check_str+3);
					}*/
					netinterface_status netStatusCurr[10] = {0};
					int NetCableInsert = 0;
					int NetCableOut = 0;
					int NetCableInsertPort = 0;
					char NetName[32] = {0};
					getNetPortStatus(netStatusCurr, 10);

					int j;
					for (j = 0; j < 10; j++)
					{
						if (netStatus[j].status == 0 && netStatusCurr[j].status == 1)
						{

							NetCableInsert = 1;
							NetCableInsertPort = j;
							dzlog_debug("netStatus = %s oldstatus = %d newstatus = %d", netStatus[j].net_name, netStatusCurr[j].status, netStatus[j].status);
						}
						else if (netStatus[j].status == 1 && netStatusCurr[j].status == 0)
						{
							NetCableOut = 1;
							NetCableInsertPort = j;
							dzlog_debug("netStatus = %s oldstatus = %d newstatus = %d", netStatus[j].net_name, netStatusCurr[j].status, netStatus[j].status);
						}
					}

					if (NetCableInsert)
					{
						// if (toAlarmFlag(i))
						//{
						sprintf(NetName, "%s", netStatus[NetCableInsertPort].net_name);
						cJSON *data = setData_NetCable(NetName, i, "NetCableInsert");
						alarm_publish(data, ALARM_SERVICE_NETPORT);
						//}
					}
					if (NetCableOut)
					{
						// if (toAlarmFlag(i))
						//{
						sprintf(NetName, "%s", netStatus[NetCableInsertPort].net_name);
						cJSON *data = setData_NetCable(NetName, i, "NetCablePullOut");
						alarm_publish(data, ALARM_SERVICE_NETPORT);
						//}
					}

					memset(netStatus, 0x00, sizeof(netStatus));
					memcpy(netStatus, netStatusCurr, sizeof(netStatus));
				}
				
				// 网络链路时延告警(默认对qmex服务ip以及端口测量)
				else if (strcmp(g_st_security_rule[i].indicator, "netlinkDelay") == 0)
				{

					char *protocol = "tcp";
					// int avgDelay = check_delay(g_client_info->server_addr, g_client_info->port, 500);
					if (g_all_netInfo.avg > g_st_security_rule[i].threshold)
					{	
						if (g_st_security_rule[i].isAlarm != 1)
						{
							dzlog_debug("Delay1: %d \n", g_all_netInfo.avg );
							g_st_security_rule[i].isAlarm = 1;
							cJSON *data = setData_netlinkDelay(g_mqtt_ob.clientInfo.server_addr, i, "netlinkDelay", g_mqtt_ob.clientInfo.port, protocol, g_all_netInfo.avg);
							alarm_publish(data, ALARM_SERVICE_NETLINK);
							//告警后 主动上报 功能暂废除
							// char uuid[64] = {0};
							// GF_GetGUID(uuid);
							// terminalNetLinkStatus(uuid, g_mqtt_ob.clientInfo.device_id);	
						}
					}
					else
					{
						if (g_st_security_rule[i].isAlarm != 0)
						{
							g_st_security_rule[i].isAlarm = 0;
						}
					}
				}
				// 网络中断(默认对qmex服务ip以及端口测量)
				// else if (strcmp(g_st_security_rule[i].indicator, "netlinkBreak") == 0)
				// {
				// 	// char *protocol = "tcp";
				// 	// // int avgDelay = check_delay(g_mqtt_ob.clientInfo.server_addr, g_mqtt_ob.clientInfo.port, 500);
				// 	// if (g_all_netInfo.avg >= g_st_security_rule[i].threshold)
				// 	// {
				// 	// 	cJSON *data = setData_netlinkBreak(g_mqtt_ob.clientInfo.server_addr, i, "netlinkBreak", g_mqtt_ob.clientInfo.port, protocol);
				// 	// 	alarm_publish(data, ALARM_SERVICE_NETLINK);
				// 	// }
				// 	char *protocol = "tcp";
				// 	// // int avgDelay = check_delay(g_client_info->server_addr, g_client_info->port, 500);
				// 	dzlog_debug("Break: %d \n", g_all_netInfo.avg);

				// 	if (g_all_netInfo.avg > g_st_security_rule[i].threshold)
				// 	{
				// 		if (g_st_security_rule[i].isAlarm != 1)
				// 		{
				// 			g_st_security_rule[i].isAlarm = 1;
				// 			cJSON *data = setData_netlinkBreak(g_mqtt_ob.clientInfo.server_addr, i, "netlinkBreak", g_mqtt_ob.clientInfo.port, protocol);
				// 			alarm_publish(data, ALARM_SERVICE_NETLINK);
				// 		}
				// 	}
				// 	else
				// 	{
				// 		if (g_st_security_rule[i].isAlarm != 0)
				// 		{
				// 			g_st_security_rule[i].isAlarm = 0;
				// 		}
				// 	}
				// }
			}
		}
		sleep(3);
	}
}

int set_cmd_by_context(char *sessionId, char *command, char *cmdTmp)
{
	// char cmdTmp[1024];
	int ret = 0;
	ST_CMD_CONTEXT *cmdContext = hash_get(&g_cmd_map, sessionId);
	if (cmdContext)
	{
		// dzlog_info("map_get cmdContest addr cmdContest pwd[%s], sessionTime[%lu]",  cmdContext->pwd, cmdContext->sessionTime);
		time_t currTime = time(NULL);
		if (currTime - cmdContext->sessionTime < 5 * 60)
		{
			sprintf(cmdTmp, "cd %s && %s", cmdContext->pwd, command);
			ret = 1;
		}
		else
		{
			strcpy(cmdTmp, command);
			ret = 0;
		}
	}
	else
	{
		strcpy(cmdTmp, command);
		ret = 0;
	}
	// dzlog_info("set_cmd_by_context command[%s],cmdTmp[%s]",command, cmdTmp);

	return ret;
}

int get_net_info(char *mid, ST_NETINFO *netInfo, char *model)
{
	// dzlog_info("----get_net_info------");
	int ret = 0;
	double delaySum = 0;
	ST_NET_CONTEXT *netContext = NULL;

	// 休眠1秒，确保网络测试执行完成
	sleep(1);
	// pthread_mutex_lock(&net_test_mutex);
	// ST_NET_CONTEXT *netContext = hash_get(&g_net_map, mid);
	// pthread_mutex_unlock(&net_test_mutex);
	// 根据模块获取对应的全局对象
	if (strstr(model, "device"))
		netContext = &g_device_netContext;
	else if (strstr(model, "security"))
		netContext = &g_security_netContext;
	else if (strstr(model, "diagnostics"))
		netContext = &g_diagnostics_netContext;
	if (netContext)
	{
		if (strcmp(mid, netContext->mid))
		{
			// dzlog_info("----get_net_info data error mid[%s],netContext->mid[%s]----", mid,netContext->mid);
			memset(netInfo, 0x00, sizeof(ST_NETINFO));
			// pthread_mutex_unlock(&net_test_mutex);
			return 0;
		}
		// dzlog_info("----get_net_info netContext[%p] mid[%s] netContext->mid[%s] netContext->curr_num[%d] netContext->recv_num[%d] ------",netContext, mid,netContext->mid, netContext->curr_num, netContext->recv_num);
		// dzlog_info("----get_net_info 111 netContext->delay[netContext->curr_num -1][%d]------",netContext->delay[netContext->curr_num -1]);
		netInfo->duration = netContext->send_num;
		netInfo->ttl = 0;
		netInfo->last = netContext->delay[netContext->curr_num - 1];
		int i;
		netInfo->best = netContext->delay[0];
		netInfo->avg = netContext->delay[0];
		netInfo->worst = netContext->delay[0];

		// 偶尔send_num会出现无效大，会崩溃
		if (netContext->send_num > TEST_MAX_NUM)
		{
			// dzlog_info("!!!!!!!!!netContext->send_num[%d] > TEST_MAX_NUM mid[%s]!!!!!",netContext->send_num,mid);
			netContext->send_num = TEST_MAX_NUM;
		}
		for (i = 0; i < netContext->send_num; i++)
		{
			// dzlog_info("----get_net_info delay[%d]:%lf------",i,netContext->delay[i]);
			if (netContext->delay[i] > netInfo->worst)
				netInfo->worst = netContext->delay[i];
			if (netContext->delay[i] < netInfo->best)
				netInfo->best = netContext->delay[i];
			delaySum += netContext->delay[i];
		}
		netInfo->avg = delaySum / netContext->send_num;
		netInfo->sent = netContext->send_num;
		netInfo->recv = netContext->recv_num;
		netInfo->lossPct = (float)(1.0 - ((float)netContext->recv_num / (float)netContext->send_num));
		netInfo->stddev = calculate_jitter(netContext->delay, netContext->send_num);
		// dzlog_info("duration[%d], last[%d], best[%d], avg[%d], worst[%d], sent[%d], recv[%d], lossPct[%f], stddev[%f]",netInfo->duration,netInfo->last,netInfo->best,netInfo->avg,netInfo->worst,netInfo->sent,netInfo->recv,netInfo->lossPct,netInfo->stddev);
		// 取完数据释放申请的内存
		// dzlog_info("----free(netContext) 111 netContext[%p] mid[%s]------",netContext, mid);
		// free(netContext);
		// dzlog_info("----free(netContext) 222------");
		// netContext = NULL;
		// hash_put(&g_net_map, mid, NULL);
		// dzlog_info("----hash delete ------");
		// 取完把全局对象清空
		memset(netContext, 0x00, sizeof(ST_NET_CONTEXT));
	}
	else
	{
		// dzlog_info("----get_net_info 222------");
		memset(netInfo, 0x00, sizeof(ST_NETINFO));
	}
	// pthread_mutex_unlock(&net_test_mutex);

	return 0;
}

int mqtt_send_net_test(char *mid, int test_num, char *model)
{
	// printf("----mqtt_send_net_test------\n");
	//  上报网络测试包
	{
		cJSON *json = NULL;
		cJSON *params = NULL;
		cJSON *service = NULL;
		cJSON *services = NULL;
		cJSON *dev = NULL;
		cJSON *devs = NULL;
		char *pcJson = NULL;
		char test_data[16] = {0};

		// dzlog_info("----mqtt_send_net_test------");
		generate_random_string(test_data, 16);
		// int i;
		// // for (i = 0; i < sizeof(test_data); i++) {
		// for (i = 0; i < 16; i++)
		// {
		// 	test_data[i] = '1';
		// }
		// test_data[15] = '\0';

		// 测试频率最大为10次
		if (test_num > TEST_MAX_NUM)
			test_num = TEST_MAX_NUM;

		int j;
		for (j = 0; j < test_num; j++)
		{
			// 组包
			json = cJSON_CreateObject();
			if (json)
			{
				cJSON_AddStringToObject(json, "deviceSn", g_mqtt_ob.clientInfo.device_id);
				cJSON_AddStringToObject(json, "cmd", "netDelayTest");
				cJSON_AddStringToObject(json, "model", model);
				cJSON_AddStringToObject(json, "service", "netDelayService");
				char uuid[64] = {0};
				GF_GetGUID(uuid);
				cJSON_AddStringToObject(json, "mid", mid);
				cJSON_AddStringToObject(json, "sid", uuid);
				cJSON_AddNumberToObject(json, "test_num", test_num);
				cJSON_AddNumberToObject(json, "curr_num", j + 1);
				cJSON_AddStringToObject(json, "test_data", test_data);
				struct timeval tv;
				gettimeofday(&tv, NULL);
				long long milliseconds = (long long)(tv.tv_sec) * 1000 + (long long)(tv.tv_usec) / 1000;
				// dzlog_info("mqtt_send_net_test sendtime: %lld", milliseconds);
				// char timetemp[64] = {0};
				// sprintf(timetemp, "%ld", milliseconds);
				cJSON_AddNumberToObject(json, "sendTime", milliseconds);
				{
					pcJson = cJSON_PrintUnformatted(json);
				}
				cJSON_Delete(json);
			}

			publishMessage("/v1/devices/test/netTestRequest", pcJson);
			free(pcJson);
			// 每一秒发一个测试包
			sleep(1);
		}
	}
	/*
	struct timeval tv;
	gettimeofday(&tv, NULL);
	long long g_netTestMilliSeconds = (long long)(tv.tv_sec) * 1000 + (long long)(tv.tv_usec) / 1000;
	dzlog_info("网络延时测试 发送前毫秒级时间戳： %lld", g_netTestMilliSeconds);
	*/

	return 0;
}

//时延监控 发送nettest包的频率
void *net_Info_loop_thread(void *param)
{
	pthread_detach(pthread_self());
	dzlog_info("net_Info_loop_thread start");
	while(1)
	{
		char net_uuid[64] = {0};
		GF_GetGUID(net_uuid);
		mqtt_send_net_test(net_uuid, 1, "security");
		ST_NETINFO netInfo;
		get_net_info(net_uuid, &netInfo, "security");
		// 用告警的网络延时对象作为全局延时对象，其他模块可以都从这获取
		//是否需要 加锁保护全局变量访问
		g_all_netInfo = netInfo;
		sleep(900);   // 时延监控 15分钟一次
	}
	dzlog_info("net_Info_loop_thread end");
	return 0;
}

/*
int mqtt_recv_net_test(char *pcJson, ST_NETINFO netInfo)
{

	// 接收网络测试包
	cJSON *json = NULL;
	char cmd[32] = {0};
	json = cJSON_Parse(pcJson);
	if (json)
	{
		strncpy(cmd, cJSON_GetObjectItem(json, "cmd")->valuestring, sizeof(cmd));


		cJSON_Delete(json);
	}

	gettimeofday(&tv, NULL);
	long long milliseconds2 = (long long)(tv.tv_sec) * 1000 + (long long)(tv.tv_usec) / 1000;
	dzlog_info("网络延时测试 发送后毫秒级时间戳： %lld", milliseconds2);

}
*/

int testNetManage(char *pcJson)
{
	// printf(pcJson);
	// dzlog_info("----testNetManage------");
	cJSON *json = NULL;
	cJSON *params = NULL;
	cJSON *json2 = NULL;
	cJSON *body = NULL;
	/// req
	char mid[64] = {0};
	char sid[64] = {0};
	char model[64] = {0};
	char service[32] = {0};
	char cmd[32] = {0};
	char command[128] = {0};
	char sessionId[64] = {0};

	char deviceSn[32] = {0};
	char deviceId[32] = {0};
	double sendTime;
	double recvTime;
	double msDelay;
	int test_num;
	int curr_num;
	ST_NET_CONTEXT *netContext = NULL;

	json = cJSON_Parse(pcJson);
	if (json)
	{
		strcpy(mid, cJSON_GetObjectItem(json, "mid")->valuestring);
		strcpy(sid, cJSON_GetObjectItem(json, "sid")->valuestring);
		strcpy(model, cJSON_GetObjectItem(json, "model")->valuestring);
		test_num = cJSON_GetObjectItem(json, "test_num")->valueint;
		curr_num = cJSON_GetObjectItem(json, "curr_num")->valueint;

		sendTime = cJSON_GetObjectItem(json, "sendTime")->valuedouble;
		recvTime = cJSON_GetObjectItem(json, "recvTime")->valuedouble;
		/*struct timeval tv;
		gettimeofday(&tv, NULL);
		long long milliseconds = (long long)(tv.tv_sec) * 1000 + (long long)(tv.tv_usec) / 1000;
		*/

		struct timeval tv;
		gettimeofday(&tv, NULL);
		long long milliseconds = (long long)(tv.tv_sec) * 1000 + (long long)(tv.tv_usec) / 1000;
		// dzlog_info(" milliseconds: %lld", milliseconds);
		/// dzlog_info("testNetManage milliseconds[%lld]", milliseconds);
		// msDelay = (double)(milliseconds - sendTime);
		msDelay = (double)(recvTime - sendTime);
		// dzlog_info("testNetManage msDelay[%lf]", msDelay);
		// dzlog_info("testNetManage mid[%s],sid[%s],test_num[%d],curr_num[%d]", mid,sid,test_num,curr_num);
		// dzlog_info("22 testNetManage sendTime[%lld],milliseconds[%lld],msDelay[%lld]", sendTime,milliseconds,msDelay);
		{
			int ret = 0;
			// pthread_mutex_lock(&net_test_mutex);
			// netContext = hash_get(&g_net_map, mid);
			// pthread_mutex_unlock(&net_test_mutex);
			// 根据模块获取对应的全局对象
			if (strstr(model, "device"))
				netContext = &g_device_netContext;
			else if (strstr(model, "security"))
				netContext = &g_security_netContext;
			else if (strstr(model, "diagnostics"))
				netContext = &g_diagnostics_netContext;

			if (netContext)
			{
				/*
				if(strcmp(mid,netContext->mid))
				{
					dzlog_info("----get_net_info data error mid[%s],netContext->mid[%s]----", mid,netContext->mid);
					//pthread_mutex_unlock(&net_test_mutex);
					cJSON_Delete(json);
					return 0;
				}*/
				// dzlog_info("testNetManage get netContext");
				// 如果已有，则更新数据
				// 放入MID作为校验
				strcpy(netContext->mid, mid);
				netContext->delay[curr_num - 1] = msDelay;
				netContext->recv_num++;
				netContext->curr_num = curr_num;
				netContext->send_num = test_num;
			}
			/*
			else
			{
				//没有则创建net数据
				netContext = NULL;
				//dzlog_info("testNetManage 32 netContest[%p],%d",netContext,sizeof(ST_NET_CONTEXT));
				netContext = malloc(sizeof(ST_NET_CONTEXT));
				dzlog_info("testNetManage create netContest[%p] msDelay[%lf]",netContext,msDelay);
				//放入MID作为校验
				strcpy(netContext->mid ,mid);
				netContext->delay[curr_num-1] = msDelay;
				//netContext->delay[1] = 100;
				netContext->send_num = test_num;
				netContext->recv_num++;
				netContext->curr_num = curr_num;
				//pthread_mutex_lock(&net_test_mutex);
				hash_put(&g_net_map, mid, netContext);
				//pthread_mutex_unlock(&net_test_mutex);

			}
			pthread_mutex_unlock(&net_test_mutex);
			*/

			//	return ret;
		}

		cJSON_Delete(json);
	}
	return 0;
}

void *netTest_thread(void *param)
{
	char perr;
	char *jsonStr = NULL;

	// dzlog_info("netTest_thread start...");
	pthread_detach(pthread_self());

	// g_cmd_map = {malloc(HASHSIZE * sizeof(ST_CMD_CONTEXT *)), HASHSIZE};
	g_net_map.data = malloc(HASHSIZE * sizeof(ST_NET_CONTEXT *));
	g_net_map.size = HASHSIZE;

	// 从队列获取命令请求
	while (1)
	{
		jsonStr = (char *)cQRcv(g_mqtt_ob.netPq, &perr);
		if (perr == ERR_Q_EMPTY)
		{
			// dzlog_info("cmd queue is empty...");
		}
		else if (perr == ERR_Q_NONE)
		{
			// dzlog_info("netTest_thread get cjson [%s]",(char*)jsonStr);

			// 解析报文获取包的延时数据
			testNetManage(jsonStr);

			free(jsonStr);
		}

		// sleep(5 * 60);
		usleep(1000);
	}
}

void sys_log_publish_jsl()
{
	char loginTime[128] = {0};
	char user[32] = {0};
	char srcIp[32] = {0};
	int srcPort = 0;
	char dstIp[32] = {0};
	int dstPort = 22;
	char cmd[128] = {0};
	char cmdOutput[1024] = {0};
	char opTime[128] = {0};
	char loginTimeZ[128] = {0};

	// 过滤系统日志文件获取相关信息
	{
		// 获取本地ssh端口和IP

		// 获取本地 IP 地址
		S_NETCARD sNetCard[100];
		int ret = wiredModules(sNetCard);

		if (ret > 0)
		{
			strcpy(dstIp, sNetCard[0].ip);
		}
		else
		{
			strcpy(dstIp, "127.0.0.1");
		}

		char cmd[128] = {0};
		char result[128] = {0};
		FILE *fp;
		int i = 0;
		char output[1024] = {0};
		strcpy(cmd, "grep -r \"Accepted password\" /var/log/messages");
		// dzlog_info("sys_log_publish cmd[%s]",cmd);
		fp = popen(cmd, "r");
		if (fp == NULL)
		{
			dzlog_error("cmd exec error");
			return;
		}
		while (!feof(fp))
		{
			if (fgets(output, 1024, fp) != NULL)
			{
				if (i >= 5)
					break;

				char logtime[16] = {0};
				strncpy(logtime, output, 15);
				struct tm tm_time;
				memset(&tm_time, 0, sizeof(struct tm));

				if (strptime(logtime, "%b %d %H:%M:%S", &tm_time) != NULL)
				{
					// 获取当前年份
					time_t now = time(NULL);
					struct tm *current_time = localtime(&now);
					tm_time.tm_year = current_time->tm_year;
				}

				// 提取 root 用户
				char *start = strstr(output, "for ");
				if (start != NULL)
				{
					start += 4;
					char *end = strstr(start, " from");
					if (end != NULL)
					{
						int user_len = end - start;

						strncpy(user, start, user_len);
						user[user_len] = '\0';
					}
				}

				// 提取 IP 地址
				start = strstr(output, "from ");
				if (start != NULL)
				{
					start += 5;
					char *end = strstr(start, " port");
					if (end != NULL)
					{
						int ip_len = end - start;

						strncpy(srcIp, start, ip_len);
						srcIp[ip_len] = '\0';
					}
				}

				// 提取端口号
				start = strstr(output, "port ");
				if (start != NULL)
				{
					start += 5;
					srcPort = atoi(start);
				}

				strftime(opTime, sizeof(opTime), "%Y %b %d %H:%M:%S", &tm_time);

				strcpy(loginTime, opTime);
				sprintf(cmd, "ssh %s", dstIp);
				strcpy(cmdOutput, "Password auth succeeded");

				// dzlog_info("loginTime[%s] user[%s]srcIp[%s],srcPort[%d],dstIp[%s]", loginTime, user, srcIp, srcPort, dstIp);

				int CTimeFlag = to_time(loginTime, loginTimeZ, "%Y %b %d %H:%M:%S");
				if (CTimeFlag)
				{
					continue;
				}

				// 上报数据
				{
					cJSON *json = NULL;
					cJSON *params = NULL;
					cJSON *service = NULL;
					cJSON *services = NULL;
					cJSON *dev = NULL;
					cJSON *devs = NULL;
					char *pcJson = NULL;

					// dzlog_info("----sys_log_publish------");

					// 组包
					json = cJSON_CreateObject();
					if (json)
					{
						cJSON_AddItemToObject(json, "devices", devs = cJSON_CreateArray());
						cJSON_AddItemToArray(devs, dev = cJSON_CreateObject());
						cJSON_AddStringToObject(dev, "deviceId", g_mqtt_ob.clientInfo.device_id);
						cJSON_AddStringToObject(dev, "deviceSn", g_mqtt_ob.clientInfo.device_id);
						cJSON_AddItemToObject(dev, "services", services = cJSON_CreateArray());
						cJSON_AddItemToArray(services, service = cJSON_CreateObject());
						cJSON_AddStringToObject(service, "service", "sshMonitor");
						char uuid[64] = {0};
						GF_GetGUID(uuid);
						cJSON_AddStringToObject(service, "mid", uuid);
						cJSON *data = cJSON_CreateObject();
						cJSON_AddStringToObject(data, "user", user);
						cJSON_AddStringToObject(data, "srcIp", srcIp);
						cJSON_AddNumberToObject(data, "srcPort", srcPort);
						cJSON_AddStringToObject(data, "dstIp", dstIp);
						cJSON_AddNumberToObject(data, "dstPort", dstPort);

						cJSON_AddStringToObject(data, "loginTime", loginTimeZ);
						cJSON_AddStringToObject(data, "opTime", loginTimeZ);
						cJSON_AddStringToObject(data, "cmd", cmd);
						cJSON_AddStringToObject(data, "cmdOutput", cmdOutput);
						cJSON_AddItemToObject(service, "data", data);
						char t[128] = {0};
						systemDate(t);
						cJSON_AddStringToObject(service, "eventTime", t);

						{
							pcJson = cJSON_PrintUnformatted(json);
						}
						cJSON_Delete(json);
					}

					publishMessage("/v1/devices/device/events", pcJson);
					free(pcJson);
				}
			}
			i++;
		}
		pclose(fp);
	}
}
